Reputation: 1165
I have the following file I'm trying to write unit tests for:
import { document } from '../../globals';
const Overlay = () => {
console.log(document.getElementsByTagName()); // this outputs 'undefined'
};
I'm struggling to mock the getElementsByTagName
function. My test looks like this.
import { document } from '../../globals';
jest.mock('../../globals', () => ({
document: {
getElementsByTagName: jest.fn().mockReturnValue('foo')
}
}));
console.log(document.getElementsByTagName()); // this outputs 'foo'
But unfortunately, the console.log
in the top file always outputs undefined
. It can see the document object and the getElementsByTagName
mock, but the return value is always undefined
.
If I console.log(document.getElementsByTagName)
I get the following:
{ getElementsByTagName:
{ [Function: mockConstructor]
_isMockFunction: true,
getMockImplementation: [Function],
mock: [Getter/Setter],
mockClear: [Function],
mockReset: [Function],
mockReturnValueOnce: [Function],
mockReturnValue: [Function],
mockImplementationOnce: [Function],
mockImplementation: [Function],
mockReturnThis: [Function],
mockRestore: [Function] },
}
But if I do the same in the other file I get this:
function () {
return fn.apply(this, arguments);
}
My suspicion is that jest.mock
is wrapping the jest.fn
mock in another function.. any ideas?
Upvotes: 27
Views: 25041
Reputation: 1647
In my case, I was using react-scripts
to run tests. (Within my package.json
the test
attribute was set to react-scripts test
).
Thankfully, I stumbled on this Stack Overflow answer, where I found that by default react-scripts will set jest.resetMocks to true
. In a standard jest configuration, this is false
.
This means when running with react-scripts test
, before every test run, your mock implementation will be completely reset and your mock function will return undefined
.
A couple ways to fix this:
package.json
, add a resetMocks: false
to your jest
configuration:"jest": {
...,
"resetMocks": false
}
beforeEach
functionUpvotes: 5
Reputation: 12045
.mockReturnValue()
after assignmentI encountered the same behavior and found success by calling mockFn.mockReturnValue(value)
after assignment.
For example:
import { document } from '../../globals.js'
jest.mock('../../globals.js', () => ({
document: {
getElementsByTagName: jest.fn()
}
}))
document.getElementsByTagName.mockReturnValue('foo')
console.log(document.getElementsByTagName()); // this outputs 'foo'
I have seen both patterns within the jest documentation.
mockFn.mockReturnValue(value)
where post-assignment calling is shown.jest.requireActual(moduleName)
where calling during assignment is shown.I wonder if the latter case requires some other pattern of interaction to assert on the mocked return value, but I haven't figured it out. I can't seem to replicate success using the spyOn
pattern suggested in another answer here.
Upvotes: 13