Reputation: 5062
sum.js
module.exports = function sum(a, b){
return a + b;
};
Thing.js
var sum = require("./sum");
module.exports = class Thing {
add(a, b){
return sum(a, b);
}
}
Thing.test.js
test('1 + 2 = 3', () => {
//Arrange
var Thing = require('./Thing');
var thing = new Thing();
//Act
var result = thing.add(1, 2);
//Assert
expect(result).toBe(3);
});
test('sum mocked', () => {
//Arrange
jest.mock('./sum', () => {
return jest.fn(() => 42);
});
var Thing = require('./Thing');
var thing = new Thing();
//Act
var result = thing.add(1, 2);
//Assert
expect(result).toBe(42);
});
How can I mock the sum 'require' dependency when testing? I get the following error.
sum mocked
expect(received).toBe(expected)
Expected value to be (using ===):
42
Received:
3
What's interesting if I run each test individually with .only, they both work just fine on their own.
In the past I've used proxyquire to do things like this but I'd like to avoid it if possible.
Upvotes: 24
Views: 39738
Reputation: 2181
Taken from the Jest Docs.
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 1);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(1);
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 2);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(2);
});
https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options
Upvotes: 10
Reputation: 172
I have the feeling that mocking works per test file. Don't ask me why ¯\_(ツ)_/¯
The approach that worked the best for me was to set the tests like this:
// sum.test.js
//Arrange
const sum = require('./sum');
test('1 + 2 = 3', () => {
//Act
const result = sum(1, 2);
//Assert
expect(result).toBe(3);
});
And:
// Thing.test.js
//Arrange
const Thing = require('./Thing');
// jest.mock are hoisted so you can keep imports/require on top
const sumSpy = jest.fn(() => 42);
jest.mock('./sum', () => sumSpy);
test('Thing', () => {
const thing = new Thing();
//Act
const result = thing.add(1, 2);
//Assert
expect(sumSpy).toHaveBeenCalledTimes(1);
expect(result).toBe(42);
});
You can even provide different mock implementations per test with something like:
sumSpy.mockImplementation(() => NaN);
Upvotes: 6
Reputation: 5062
In the test, I added
beforeEach(() => {
jest.resetModules();
});
and the tests passed as expected.
Upvotes: 21