- if you need a dumb dependency injected by your file under test then use a partial pattern so you mock only myFunction if you need it. example: const mockedMyService: Partial = { myFunction = jest.fn() }; so now you can create a spy on myFunction and then do assertion on it. example myFunctionSpy = jest.spyOn(mockedMyService, 'myFunction') and finally expect(myFunctionSpy).toHaveBeenCalledTimes(1).
- if you want to keep the original function implementation and be aware if the function is called then you can use jest.spyOn on a real function instead of jest.fn() function.
- with jest.fn() you can also replace the original function implementation using different ways: mockImplementation, mockReturnValue, mockReturnValueOnce, mock...
- Jest has an auto-mock function, it seems right to use this: jest.mock only with static class or with external dependencies compiled in ESM. Indeed the big dris method is more verbose, harder to maintain and slower compared to a simple partial empty objects.
jest.mock('./static-helper');
jest.mock('swiper', () => ({ use: jest.fn() })); // if you don't need anything back
jest.mock('swiper', () => ({ use: jest.fn().mockReturnValue(true) })); // to mock a plain function
jest.mock('swiper', () => ({ use: jest.fn().mockResolvedValue(true) })); // to mock a promise function
- This automock function described above (jest.mock('lib/module')) can be very useful with barrel import because else jest will load everything from the barrel file; so instead with this you mock the dependencies imported by the file inside your module. but you still need to define manually the mocked service using jest.MockedClass + functions prototype used with jest.fn()
const MockedStaticHelper = StaticHelper as jest.MockedClass<typeof StaticHelper>;
MockedStaticHelper.displayThing = jest.fn().mockReturnValue(true);
- You can also spy specific function of a static class like singleton using jest.spyOn(MyAPI.api(), 'myFeature').mockAndReturnValue(myMockedFeature)
- You can also mock entire libraries by mapping in the jest preset to a file, see jest.preset.js:
- Mock files: https://stackoverflow.com/questions/49685265/jest-mock-user-module-in-all-test-files
- Mock mores: https://www.lucasamos.dev/articles/jestselectivemocking
You can also mock to return different results on each call using mockReturnValueOnce
myMock
.mockReturnValueOnce(10) // return 10 on the first call
.mockReturnValueOnce('x') // return 'x' on the second call
.mockReturnValue(true); // return true anytime after that
If you need more options you can use jest-when to return specific response based on the function parameter
when(fn).calledWith(1).mockReturnValue('yay!')
Another case is the Selective mocking or module functions:
import { functionOne, functionTwo } from '../src/functions';
jest.mock('../src/functions', () => {
const originalModule = jest.requireActual('../src/functions');
return {
__esModule: true,
...originalModule,
functionTwo: jest.fn(() => 'functionTwo mocked implementation'),
};
});
test('function one', () => {
expect(functionOne()).toEqual('functionOne original implementation');
});
test('function two', () => {
expect(functionTwo()).toEqual('functionTwo mocked implementation');
});
example to check the arguments that the mock has been called with
expect(mock).toHaveBeenNthCalledWith(1, '1st call args'); // called with '1st call args' the first time
expect(mock).toHaveBeenNthCalledWith(2, '2nd call arg 1', '2nd call arg 2'); // called with '2nd call arg 1' and '2nd call arg 2' the second time
exemple how to check that an object contains a property with another object
expect(state.active.active).toEqual(true)
expect(state.active.data).toEqual(expect.any(Array))
expect(state.active.ID).toEqual(expect.any(String))
expect(state).toEqual(expect.objectContaining({ myProp: expect.any(Object)}))
expect(state.active).toMatchObject({
active: true,
data: expect.any(Array),
ID: expect.any(String)
});
- jestjs/jest#936
- https://www.emgoto.com/mocking-with-jest/
- https://www.automasean.blog/js-testing-practices/
- https://codewithhugo.com/jest-mock-spy-module-import/
- https://generic-ui.com/blog/mocking-dependencies-in-angular
- https://indepth.dev/posts/1240/create-your-angular-unit-test-spies-automagically
- https://ordina-jworks.github.io/testing/2018/08/03/testing-angular-with-jest.html
- https://www.strv.com/blog/quickest-simplest-way-mocking-module-dependencies-jest-engineering
-
https://stackoverflow.com/questions/63853066/lazy-load-imports-from-barrel-file-in-jest
-
use esbuild to merge all the tests of the lib into a file
-
use a jest transformer to convert to file import
-
use a mock generation script to map to the correct file
-
map case by case manually to the right file (only necessary)
-
use a secondary entry points for jest (link index-jest in jest.preset)
-
use NX_BATCH_MODE true to run test in batch