Jest

Jest #

Jest cheat sheet #

Mock vs Spy #

https://www.developright.co.uk/posts/jest-mock-vs-jest-spyon-what-to-use-for-mocking.html

Jest Mock AWS S3 operations #

The following block mocks the getSignedUrl() operation

jest.mock('aws-sdk', () => {
    class mockS3 {
        getSignedUrl(op, obj) {
            return 'url';
        }
    }
    
    return {
        ...jest.requireActual('aws-sdk'),
        S3: mockS3,
    };
});

Jest mock a function from a module #

import * as Utils from './utils';

beforeAll(() => {
    mockQuery = jest.spyOn(Utils , ‘query');
    mockQuery.mockImplementation(() => {});
});

beforeEach(() => {
    mockQuery.mockClear();
});


test(‘test’, () =>{
    ....
    expect(mockQuery).toHaveBeenCalledTimes(1);
    expect(mockQuery.mock.calls[0], ‘test’);
});

Jest mock partial modules #

Example of mocking node-fetch

const fetchFn = jest.fn();
const { Response } = jest.requireActual('node-fetch');

jest.mock('node-fetch', () => {
    const originalModule = jest.requireActual('node-fetch');
    const mocked = fetchFn;
    Object.assign(mocked, originalModule);
    return mocked;
});

beforeEach(() => {
    fetchFn.mockClear();
});

test('200 status', async () => {
    fetchFn.mockReturnValueOnce(Promise.resolve(new Response('Success')));
}

Test for throw #

Wrap it an arrow function

expect(() => myFunc() ).toThrow();

Jest mocking documentation #

https://jestjs.io/docs/es6-class-mocks

How to organize test files #

src/myfile.ts
src/test/myfile.int.test.ts  <- integration
src/test/myfile.unit.test.ts
src/test/.generic.unit.test.ts  <- generic tests not related to a file
  • To run only integration tests “jest .int.”
  • To run only unit tests “jest .unit.”

If global functions like describe, test etc are not recognized #

Add “jest” into compilerOptions.types property of tsconfig.json

toHaveProperty instead of toHaveBeenCalledWith #

Use .toHaveProperty() instead of “toHaveBeenCalledWith(expect.objectContaining( “ to show better errors when tests fails

Properties with dots #

toHaveProperty test function needs special handling if you have properties with dots as the default behavior is to check for nested properties.

Fix: Use the array overload instead: expect(response).toHaveProperty(['TLS1.0'])

Expect a function to be called with an object that contain an array of specific length #

expect(callbackFn).toBeCalledWith(
    expect.objectContaining({
        success: false,
        reqErrors: Array(1).fill(expect.anything()),
        itemErrors: []
    })
);

Test if object has specific properties #

expect(json).toEqual(
    expect.objectContaining({
        title: expect.any(String),
        contentHtml: expect.any(String),
        categories: expect.any(Array),
        creator: expect.any(String),
        pubDate: expect.any(String),
        updated: expect.any(String)
    })
);

Test if array contains at least 1 item with the schema #

expect(dbItems.Items).toContainEqual(
    expect.objectContaining({
    contentHtml: expect.stringContaining('href="/s/7ZM6VGMN')
    })
);

.toContain vs .toContainEqual #

  • .toContain uses ===, a strict equality check.
  • .toContainEqual: when you want to check that an item with a specific structure and values is contained in an array