Skip to content

Latest commit

 

History

History
123 lines (92 loc) · 5.28 KB

utils-jest.md

File metadata and controls

123 lines (92 loc) · 5.28 KB

Jest

Books

Mocks

  • 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...

Mocks

  • 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 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');
});

Expect

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)
});

Articles

Barrel