Sam Johnston - Senior Software Engineer

Sam Johnston

Senior Software Engineer
AWS, NodeJS, React

Thursday, 19 August 2021

Home » Articles » Jest Snippets

Jest Snippets

Jest Snippets

Jest snippets for the tedious bits

Test that a method throws something

it('Throws an error', () => {
  expect(() => {
    methodThatThrows();
  }).toThrow(Error);
});

// async function
it('Throws an error', () => {
  await expect(methodThatThrows()).rejects.toThrow('Constructor Message');
});

Mock a specific exported method, whilst leaving everything else unmocked.

jest.mock('./pathToFile', () => ({
  ...jest.requireActual('./pathToFile'), // Mock all exports
  config: {
    ...jest.requireActual('./pathToFile').config, // Mock nested export
    getEnv: () => ({
      ...jest.requireActual('../../../src/environment').config.getEnv(), // Mock deeply nested export
      isEnabled: jest.fn().mockReturnValue(true), // Override specific value.
    }),
  },
}));

Mock process.env values to toggle features under test

describe('environmental variables', () => {
  // First we store the original process.env in a const:
  const OLD_ENV = process.env;

  beforeEach(() => {
    // Resets the module registry - the cache of all required modules.
    // This is useful to isolate modules where local state might conflict between tests.
    jest.resetModules();

    // Create a copy of process.env so we can change its properties safely
    process.env = { ...OLD_ENV };
  });

  afterAll(() => {
    // Restore the original process.env after we've run our tests
    process.env = OLD_ENV;
  });

  test('will receive process.env variables', () => {
    // Set the process.env properties to the values we want in a given test
    // This makes changes to the copied object, not the original implementation
    process.env.FF_STOCK_MANAGEMENT_ENABLED = 'false';
  });
});

Mock an export

// Default Export
jest.mock('../../hooks/useCustomHook', () => ({
  __esModule: true,
  default: jest.fn().mockImplementation(() => ({ loading: false })),
}));

// Named Export
jest.mock('../../hooks/useCustomHook', () => ({
  useCustomHook: jest.fn();
}));

Spy on mocked an exports or remock them for specific test

jest.mock('../../hooks/useCustomHook', () => ({
  useCustomHook: jest.fn(),
}));

const mockInternalMethod = jest.fn();
jest.mock('hooks/useComplexCustomHook', () => ({
  useComplexCustomHook: () => ({
    internalMethod: mockUseTracking,
  }),
}));

beforeEach(() => {
  useCustomHook.mockReturnValue({ customProp: 'value' });
});

it('was called', () => {
  expect(useCustomHook).toHaveBeenCalledWith();
});

it('side effect was called', () => {
  expect(mockInternalMethod).toHaveBeenCalled();
});

Mock the current window location with a specific URL

describe('current window location', () => {
  const OLD_LOCATION = window.location;

  beforeEach(() => {
    delete window.location;
  });

  afterAll(() => {
    process.env = OLD_ENV;
    window.location = OLD_LOCATION;
  });

   test('is the correct location', () => {

    window.location = new URL('https://www.example.com');
    getLoginApiHost();

    expect(window.location.href)).toEqual('https://www.example.com');
    expect(window.location.protocol)).toEqual('https');
    // etc...
  });
});