jest.mock(module)和jest.fn()有什么区别 [英] What is the difference between jest.mock(module) and jest.fn()

查看:207
本文介绍了jest.mock(module)和jest.fn()有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have tried couple different ways of defining the mock function and all of my tries failed. When I try to define it as follow:

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]}

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

As my third try I defined the mock as:

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.

我想知道问题出在哪里,这三种定义模拟的方式有何不同?

I wonder what is the problem and how these 3 ways of defining mock are different?

P.S.可以在这里找到代码:

P.S. the code can be find here: Write a Unit test in Jest for a React form

推荐答案

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

In the first example you say that when ever the module '../src/data/server' is imported in some other module it will be {server: {report: jest.fn()}}. In the next line you try to use server. The problem is that you never import the module that you mock. Maybe in the module that you test server is {server: {report: jest.fn()}}, but in you in test server is just undefined as you never import it. To fix this also have to import it.

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.

In the second example it seams like jest.mock just returns jest.

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

The last example fails cause you never call st.report.

回到主要问题. jest.mockjest.fn

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

jest.mock replaces one module with either just jest.fn, when you call it with only the path parameter, or with the returning value of the function you can give it as the second parameter. So in your first example when ever in one of your files you wanna test or in the test itself, '../src/data/server' is imported it will be {server: {report: jest.fn()}}.

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

Which brings us the jest.fn(). This will return a spy. A spy is a function that can remember each call that was made on it, and with which parameters.

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

Lets say you have a module that you wanna test:

import server from './data/server'

server.report('test123')

要测试此调用是否使用正确的参数,您需要使用可以控制的方式将此依赖关系模拟为'./data/server'.

To test that this call was made with the correct parameter you need to mock this dependency to './data/server' with something you can control.

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函数.然后您可以期望使用正确的参数调用它.

What happens here is that before all the import stuff starts jest replaces '../src/data/server' with your mock implementation, so when fileToTest is import the sever and call it, it actually call the spy function. Which you can then expect that it was called with the correct parameter.

顺便说一句.您在测试中尝试检查功能的内容将无法正常工作,因为调用间谍程序时传递的功能与传递给toBeCalledWith的功能不相同.

Btw. what you try in your test, checking for function, will not work as the functions you pass when calling the spy and the function you pass into toBeCalledWith are not identical.

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

In this case I would check for each single parameter

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"});

这篇关于jest.mock(module)和jest.fn()有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆