【问题标题】:What is the difference between jest.mock(module) and jest.fn()jest.mock(module) 和 jest.fn() 有什么区别
【发布时间】:2017-04-26 15:09:59
【问题描述】:

我尝试了几种不同的方法来定义模拟函数,但我所有的尝试都失败了。当我尝试将其定义如下:

jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}));
expect(server.report.mock).toBeCalledWith(id, data, () => {...}, () => {...});

我得到这个错误:

expect(jest.fn())[.not].toBeCalledWith()
jest.fn() value must be a mock function or spy.
Received: undefined

如果我将模拟定义为:

var spy = jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}));
expect(spy).toBeCalledWith(id, data, () => {...}, () => {...});

它返回以下错误:

    expect(jest.fn())[.not].toBeCalledWith()
    jest.fn() value must be a mock function or spy.
    Received:
      object: {"addMatchers": [Function anonymous], "autoMockOff": [Function anonymous], "autoMockOn": [Function anonymous], "clearAllMocks": [Function anonymous], "clearAllTimers": [Function anonymous], "deepUnmock": [Function anonymous], "disableAutomock": [Function anonymous], "doMock": [Function anonymous], "dontMock": [Function anonymous], "enableAutomock": [Function anonymous], "fn": [Function anonymous], "genMockFn": [Function bound getMockFunction], "genMockFromModule": [Function anonymous], "genMockFunction": [Function bound getMockFunction], "isMockFunction": [Function isMockFunction],
 "mock": [Function anonymous], "resetModuleRegistry": [Function anonymous], "resetModules": [Function anonymous], "runAllImmediates": [Function anonymous], "runAllTicks": [Function anonymous], "runAllTimers": [Function anonymous], "runOnlyPendingTimers": [Function anonymous], "runTimersToTime": [Function anonymous],"setMock": [Function anonymous], "unmock": [Function anonymous], "useFakeTimers": [Function anonymous], "useRealTimers": [Function anonymous]}

作为我的第三次尝试,我将模拟定义为:

const st = require.requireActual('../src/data/server', ()=> ({server: {report: jest.fn()}}));
st.report = jest.fn();
expect(st.report).toBeCalledWith(id, data,  () => {...}, () => {...});

我得到这个错误:

expect(jest.fn()).toBeCalledWith(expected)
Expected mock function to have been called with:
  ["1033083fe", {"address": "test address", "affiliation": "testaaa", 
  "city": "testcity", "copyright": true, "country": "testcountry", "email": "sss@test.com", "message": "testmessage", 
  "name": "testname", "phone": "1234567890", "zipcode": "12345"}, [Function anonymous], [Function anonymous]]
But it was not called.

我想知道有什么问题,这 3 种定义 mock 的方式有何不同?

附:代码可以在这里找到:Write a Unit test in Jest for a React form

【问题讨论】:

    标签: reactjs jestjs testunit enzyme


    【解决方案1】:

    在第一个示例中,您说当模块'../src/data/server' 被导入到其他模块时,它将是{server: {report: jest.fn()}}。在下一行中,您尝试使用server。问题是您永远不会导入您模拟的模块。也许在您测试的模块中server{server: {report: jest.fn()}},但在您的测试服务器中只是undefined,因为您从不导入它。要解决这个问题也必须导入它。

    import server from '../src/data/server'
    jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}));
    expect(server.report.mock).toBeCalledWith(id, data, () => {...}, () => {...});
    

    在第二个示例中,它看起来像 jest.mock 只是返回 jest

    最后一个示例失败,因为您从未调用过st.report

    回到主要问题。 jest.mockjest.fn的区别

    jest.mock 仅使用jest.fn 替换一个模块,当您仅使用路径参数调用它时,或者使用函数的返回值,您可以将其作为第二个参数。因此,在您的第一个示例中,当您想要测试的一个文件或测试本身中,'../src/data/server' 被导入,它将是{server: {report: jest.fn()}}

    这给我们带来了jest.fn()。这将返回一个间谍。 spy 是一个函数,它可以记住对其进行的每个调用,以及使用哪些参数。

    假设您有一个要测试的模块:

    import server from './data/server'
    
    server.report('test123')
    

    要测试此调用是否使用正确的参数,您需要将此依赖项模拟为 './data/server',并使用您可以控制的东西。

    import server from '../src/data/server'
    import fileToTest from '../src/fileToTest'
    jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}));
    expect(server.report.mock).toBeCalledWith('test123');
    

    这里发生的情况是,在所有导入内容开始之前,jest 将 '../src/data/server' 替换为您的模拟实现,因此当 fileToTest 导入服务器并调用它时,它实际上调用了 spy 函数。然后您可以预期它是使用正确的参数调用的。

    顺便说一句。您在测试中尝试的功能检查将不起作用,因为您在调用 spy 时传递的函数和传递给 toBeCalledWith 的函数不相同。

    在这种情况下,我会检查每个参数

    expect(server.report.mock.calls[0][0]).toBe("1033083fe");
    expect(server.report.mock.calls[0][0]).toEqual({"address": "test address", "affiliation": "testaaa", 
      "city": "testcity", "copyright": true, "country": "testcountry", "email": "sss@test.com", "message": "testmessage", 
      "name": "testname", "phone": "1234567890", "zipcode": "12345"});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 2020-11-02
      • 2021-11-18
      • 2021-04-15
      相关资源
      最近更新 更多