【问题标题】:Use Jest to mock external user module in an imported module使用 Jest 在导入的模块中模拟外部用户模块
【发布时间】:2023-03-11 19:41:01
【问题描述】:

我不知道我是否遗漏了文档中的某些内容,但我遇到了这种情况:

// test.js

import User from './user'

it("should load initial data", async() => {
  const users = new User()
  const user = await users.load()
})

// User.js

import Api from './api'

export default class User {
  async load() {
    const res = await Api.fetch() // prevent/mock this in testing
  }
}

User.js 中防止/模拟外部Api 模块的开玩笑方式是什么。我不希望User.js 在测试中发出真实的网络请求。

除此之外,我正在寻找更通用的模拟解决方案,即。假设我在 React Native 中进行测试,例如,我想模拟 NativeModules.SettingsManager.settings.AppleLocale。假设Api.fetch() 调用了上面的行,但没有发出 HTTP 请求

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    spyOnmock functions 结合使用,如 mockImplementation 将提供您正在寻找的内容。

    这是一个工作示例:

    // ---- api.js ----
    export const getData = () => {
      return Promise.resolve('hi');
    }
    
    
    // ---- user.js ----
    import { getData } from './api'
    
    export default class User {
      async load() {
        return await getData(); // mock this call in user.test.js
      }
    }
    
    
    // ---- user.test.js ----
    import User from './user'
    import * as Api from './api'; // import * so we can mock 'getData' on Api object
    
    describe('User', () => {
      it('should load initial data', async() => {
        const mock = jest.spyOn(Api, 'getData'); // create a spy
        mock.mockImplementation(() => Promise.resolve('hello')); // give it a mock implementation
    
        const user = new User();
        const result = await user.load();
        expect(result).toBe('hello');  // SUCCESS, mock implementation called
    
        mock.mockRestore(); // restore original implementation when we are done
      });
    });
    

    【讨论】:

    • 哦,太好了,所以你将模块导入到测试文件中,即使它与测试没有直接关系(即测试文件不使用 Api,但用户使用)
    • 是的!导入任何你想模拟的东西。 Jest 将替换实现,因此在测试期间任何地方使用它的任何代码都将使用模拟实现
    • 我认为这是拼图中缺失的部分!谢谢
    • 我们为什么要调用mock.mockRestore(); - 有必要吗?不做会有什么后果?
    • @lonix mockRestore 是可选的,请注意,如果未调用 mockRestore,该函数将保持模拟对于该特定测试文件中的其余测试 .如果您在所有测试中对其进行模拟,请注意它会记住所有测试中对它的 all 调用,您可以根据需要使用mockClear 清除以前的调用。
    【解决方案2】:

    如果您需要模拟对 HTTP 请求的响应,那么您应该查看 nock。它有一个干净的 API,可以灵活地为特定请求创建 HTTP 响应。

    【讨论】:

    • 我同意。但我正在寻找一个更通用的模拟解决方案,即。假设我在 React Native 中进行测试,例如,我想模拟 NativeModules.SettingsManager.settings.AppleLocale。假设Api.fetch() 调用了上面的行,但没有发出 HTTP 请求
    • @benhowdle89 然后您需要编辑您的问题以更清楚地了解您的要求。
    猜你喜欢
    • 1970-01-01
    • 2017-09-08
    • 2021-01-21
    • 2019-03-05
    • 2018-01-18
    • 2019-04-01
    • 2019-08-15
    相关资源
    最近更新 更多