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, () => {...}, () => {...});
I get the this error:
expect(jest.fn())[.not].toBeCalledWith()
jest.fn() value must be a mock function or spy.
Received: undefined
If I define the mock as :
var spy = jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}));
expect(spy).toBeCalledWith(id, data, () => {...}, () => {...});
it returns the following error:
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, () => {...}, () => {...});
And I get this error:
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. the code can be find here: Write a Unit test in Jest for a React form
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 useserver
. The problem is that you never import the module that you mock. Maybe in the module that you testserver
is{server: {report: jest.fn()}}
, but in you in test server is justundefined
as you never import it. To fix this also have to import it.In the second example it seams like
jest.mock
just returnsjest
.The last example fails cause you never call
st.report
.Back to the main question. The difference between
jest.mock
andjest.fn
jest.mock
replaces one module with either justjest.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()}}
.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:
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.What happens here is that before all the import stuff starts jest replaces
'../src/data/server'
with your mock implementation, so whenfileToTest
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.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