jest: Jest mock/spy returns undefined even when set up
š Bug Report
Mocking spy return does nothing
Iām about to lose my mind here; it seems the entire mock system is b0rked. I copy-paste the examples from the docs, and they donāt work.
To Reproduce
// __mocks__/someUtil.js
export default {
m1: jest.fn(() => 42),
}
// someUtil.test.js
import someUtil from './someUtil';
jest.mock('./someUtil')
console.log(someUtil.m1) // expected spy stuff
console.log(someUtil.m1()) // undefined š¤Æ
Other variations that also do nothing
// __mocks__/someUtil.js
throw; // does throw
export default {
m1: jest.fn(() => throw), // does NOT throw
}
// ---
export default {
m1: jest.fn().mockImplementation(() => 42),
}
// ---
export default {
m1: jest.fn().mockImplementation(() => throw), // does NOT throw
}
// ---
export default {
m1: jest.fn().mockReturnValue(42),
}
// ---
export default () => ({
m1: jest.fn().mockImplementation(() => 42),
})
// ---
export default () => ({
m1: jest.fn().mockReturnValue(42),
})
Expected behavior
As documented: it should return 42
envinfo
jest version: 24.7.1
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 28
- Comments: 28
Commits related to this issue
- stop jest from reseting mocks. see: https://github.com/facebook/jest/issues/9131\#issuecomment-668790615 — committed to ggat/code-challenge-main by ggat 2 years ago
A little late here, but I was just having this exact issue. I discovered that someone had added
resetMocks: true
to thejest.config.js
file. This means that the implementations of mock functions are reset before each test. So in our case, the mock function was being included in the mocked module at test runtime, but that mock had been reset, so it returnedundefined
.Regarding the original issue build environment, it looks like
react-scripts
does indeed addresetMocks: true
into the jest config. (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/utils/createJestConfig.js#L69) But you can override it on thejest
key of yourpackage.json
. (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/utils/createJestConfig.js#L74)resetMocks: true
was the culprite for me too.mock implementations can work with
resetMocks: true
if you setup the mocks in beforeEach, or directly inside thetest
/it
callbacks.If you set up the mocks at the top level of the module, in the describe callback (but outside of any it/test callback), or in beforeAll, they get overwritten by resetMocks AFAICT
@mateuszs Yes: I stopped using Jest. I could not figure out what the problem was; it quite possibly was coming from create-react-app, but Iād already sank far too many hours trying to get an out-of-the-box feature to work š¦
This also caught me totally by surprise. Weāve been using
restoreMocks
in ourjest.config.js
to ensure all mocked spies are reverted to their original implementation between tests.But I would have never have expected the restoration of mock functions to restore their original implementations to affect mock functions created on-the-fly with
jest.fn()
as well. Is there actually a use-case for resettingjest.fn(() => 42)
tojest.fn()
??I know (now) itās documented:
And itās probably consistent as both
jest.fn(() => 42)
andjest.spyOn(obj, 'method').mockReturnValue(42)
add mock implementations. But Iām sure it will keep tripping people up.@dstapleton92 Thank you so much, I sank a ton of time into google trying to find this answer!
For me it was
jest.resetAllMocks();
!Had a similar issue where I couldnāt figure out why the import I was trying to mock was ending up
undefined
. I was tryingbut in my component, logging
myImport
would show that it was alwaysundefined
. This, however, works:So in other words, you have to access the mocked import by actually importing it in the test rather than using the variable that you assigned the import to be mocked byā¦
None of the above worked and in my case the problem was that I was adding a mock in a
__mocks__
directory next to the file, but the import used a āscoped moduleā. I had to add a folder for the scoped module under the root mocks folder ie__mocks__/@module/file.js
.The documentation mentions it.
I had the same problem in my React project. Putting
resetMocks: false
into package.json did not fix it. I know that jest.mock is not broken but I canāt get the simple examples to work either. The weird thing is that when I use VSS interactive debugger, it shows thedummyPromise
implementation is my mocked implementation, but there is no evidence of mocked function support._isMockFunction
is undefined.I have found that I can implement the supposed jest.mock behavior by using jest.spyon, mockImplementation, and importing from mocks directory.
Broken Code
As you can see, putting the
jest.mock()
into beforeEach or in the test has no change in behavior.Working Code
Yes, esLint complains about the import from
__mocks__
and also thinks that themockDummyPromise
isnāt really a promise, but this code works.services/DummyService.js
services/mocks/DummyService.js
@HenryCharlesAnderson thanks for providing this information. I tried putting
jest.mock(...)
inside theit
callback function and itās still not working. I tried putting it underbeforeEach()
function and that didnāt work either. The only way I could get it working is to setresetMocks
to false in package.json. Any ideas why this is the case?Hereās some sample code Iāve written to test this for more context. In this example,
jest.resetMocks
in package.json is set to false and it works. The moment I set it to true, this fails. As mentioned above, movingjest.mock()
block into the callback function ofit()
andbeforeEach()
functions do not work.In my case I wanted to mock a value that got evaluated upon loading the file:
This was always returning undefined, no
resetMocks
setting.Instead I had to do: