2

I'm trying to add tests around the use of a simple config object. Let's say I have:

config.ts

export default {
  foo: "bar",
};

app.ts

import config from "./config";

export default () => {
  return config.foo;
};

app.test.ts

import App from "./app";
import config from "./config";

describe("App", () => {
  beforeEach(() => {
    jest.mock("./config", () => ({ default: { foo: "mock foo" } }));
  });

  it("returns a mocked value of config.foo", () => {
    config.foo = "baz";
    expect(App()).toBe("baz");
  });

  it("returns the default value of config.foo", () => {
    expect(App()).toBe("bar");
  });
});

The second test fails because the real config has been modified in the first test, but I want it to fail because the mock in the beforeEach has set the value to "mock foo". I think this has something to do with the config export not being a function, and so I can't do something like jest.spyOn.... However, if there's a way to mock an object, it'd save me a large refactor in the project I'm working on!

Lin Du
  • 88,126
  • 95
  • 281
  • 483
Dean James
  • 2,491
  • 4
  • 21
  • 29
  • Either store and restore original value manually, or do full jest.mock routine, as shown here https://stackoverflow.com/a/63763277/3731501 – Estus Flask Nov 28 '20 at 14:18

1 Answers1

1

You can use jest.doMock(moduleName, factory, options) to mock ./config module for each test case.

E.g.

config.ts:

export default {
  foo: 'bar',
};

app.ts:

import config from './config';

export default () => {
  return config.foo;
};

app.test.ts:

describe('App', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('returns a mocked value of config.foo', () => {
    jest.doMock('./config', () => ({ foo: 'baz' }));
    const App = require('./app').default;
    expect(App()).toBe('baz');
  });

  it('returns the default value of config.foo', () => {
    jest.doMock('./config', () => ({ foo: 'bar' }));
    const App = require('./app').default;
    expect(App()).toBe('bar');
  });
});

unit test result:

 PASS  src/stackoverflow/65049305/app.test.ts (12s)
  App
    ✓ returns a mocked value of config.foo (8ms)
    ✓ returns the default value of config.foo (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.288s
Lin Du
  • 88,126
  • 95
  • 281
  • 483