jest
jest copied to clipboard
Mocking not working
When using @swc/jest
as described in the readme for transforms in Jest tests, I can't seem to use any mocking.
With a test like this:
import got from 'got';
jest.mock('got');
describe('My Test', () => {
// ...
});
I will get:
TypeError: _got.default.mockImplementationOnce is not a function
Moving the jest.mock()
call to the top of the test file also doesn't work.
Any advice appreciated.
Same.
By design jest.mock()
is hoisting over import.
Also other methods should hoist ['mock', 'unmock', 'enableAutomock', 'disableAutomock', 'deepUnmock']
https://github.com/kulshekhar/ts-jest/blob/master/src/transformers/hoist-jest.ts
for us mocking stopped working once we added "runtime": "automatic"
Our workaround was to declare jest.mock
in another file and then import it in the test.
Our workaround was to declare
jest.mock
in another file and then import it in the test.
@gabberr, could you provide an example? I've tried it, but I still get the same error.
Hope this issue will be resolved soon. I try to switch from babel-jest
to @swc/jest
and this is the only remaining issue has left that blocks me from actually switch.
@diego-aquino here:
Create a file 'src/mocks/bunny.ts':
const mockedBunny = jest.fn()
jest.mock(
'actual/bunny/file',
() => mockedBunny
)
export default mockedBunny
Inside the test where you want to mock Bunny:
import 'src/mocks/bunny'
// OR, if you want to set mock implementation in the test
import bunnyMock from 'mocks/bunny'
bunnyMock.mockImplementation(() => 'my mocked bunny')
Try with
{
"jsc": {
"transform": {
"hidden": {
"jest": true
}
}
}
}
I just did and it seems to be working
See https://github.com/swc-project/swc/blob/2462b9941f94bc475cf9ff9c67e3b7c1f98739cc/node-swc/tests/transform/hidden_jest.js
Update: setting hidden.jest = true
is already set by @swc/jest
, but it wasn't applied, #44 fixes that.
At the moment of my message, the latest version of @swc/jest
(0.2.9) doesn't include the fix yet, but I think it'll be released in the close future
im actually still running into this, any work around?
@th3fallen have you tried https://github.com/swc-project/jest/issues/14#issuecomment-970189585 ?
@kdy1 The mentioned fix that closes this ticket was actually reverted, should this be reopened?
@gabberr it was reverted indeed in swc-jest, but a commit was added to swc itself to fix the issue: see https://github.com/swc-project/jest/pull/44#issuecomment-980601069
Can you try with an up to date swc
?
Ah, I forgot it. @Ayc0 Thank you!
There should be a test for jest's mocking mechanism: https://github.com/swc-project/jest/pull/46 So it should work now.
Can you try updating your versions of both swc and swc-jest to see if it is still broken for you? (And also can you send a way to replicate the bug? So that we can add more tests)
There should be a test for jest's mocking mechanism: #46 So it should work now.
Can you try updating your versions of both swc and swc-jest to see if it is still broken for you? (And also can you send a way to replicate the bug? So that we can add more tests)
It still doesn't work if you want to mock implementation and pass mock function as the desired export for the module that you're trying to mock. See: https://github.com/MhMadHamster/swc-jest-mock-bug/tree/master You can get around it tho by doing something like this:
import { callFnOne } from "./index";
const mockedImpl = jest.fn();
jest.mock("./to-be-mocked", () => ({
fnOne: (...args) => mockedImpl(...args),
}));
describe("", () => {
it("fnOne test", () => {
callFnOne()
expect(mockedImpl).toBeCalledTimes(1);
});
});
I forked your repo here: https://github.com/Ayc0/swc-jest-mock-bug if you want to give it a try.
I think this is related to: https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter
In the fork, you can see that I disabled swc and here are my results without swc:
and here with swc:
There seems to be a difference with the hoisting of mock*
variables, but your example still failed without SWC.
The mock*
could be investigated indeed (what do you think @kdy1?)
I think the exception with swc should match the exception without swc. Seems like a different issue though.
I agree, I'll open another issue
I opened https://github.com/swc-project/jest/issues/59 for this issue specifically.
I think we can close this one then
in my case the mocking failure is from this...
import { getUserId } from 'shared/auth';
getUserId.mockReturnValue('1');
describe("", () => {
it("getUserId test", () => {
expect(getUserId).toBe(1);
});
});
I think this is related to: https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter
I discovered that i had this issue because I was using ts-jest
before, and apparently it allows using local variables in the mock factory, hence i thought issue was in swc 😕
I think ts-jest
is using tsc
which usually changes the variables from const/let
to var
(and var
variables are hoisted to the top of the file).
But this is a guess.
Is this still an issue?
yes
Just installed latest @swc/core
and @swc/jest
and encountered the same issue.
const replaceMock = jest.fn(() => ({ type: '' }));
jest.mock('connected-react-router', () => ({
replace: replaceMock,
}));

@kylemh as mentioned above, I don't think that this code would work either with just jest (and babel)
jest.mock
isn't meant to be used with code defined out of its scope (see https://jestjs.io/docs/es6-class-mocks#calling-jestmock-with-the-module-factory-parameter)
instead you should do:
jest.mock('connected-react-router', () => {
const replaceMock = jest.fn(() => ({ type: '' }));
return {
replace: replaceMock,
};
});
so you're suggesting that ts-jest is making this work?
Maybe, I think it's related to https://github.com/swc-project/jest/issues/14#issuecomment-996890800.
But according to jest's doc, your code isn't supposed to work.
Btw, when I inject your code in babel repl with the plugin jest-hoist
, it throws this error:
But it doesn't throw with the following code (because variables starting in mock
are allowed in jest.mock):
const mockReplace = jest.fn(() => ({ type: '' }));
jest.mock('connected-react-router', () => ({
replace: mockReplace,
}));
Sorry. To be clear, what I shared was just a snippet of the test code and I didn't share any source code.
I'm calling jest.mock()
at the top-level scope of the test file and the test file is importing and testing a component that leverages connected-react-router
.
omg I was scratching my head the whole day. Lucky I saw this issue!