I have a function that I want to test and this function uses an imported module:
var a = require('./a');
function add(b) {
return a + b;
}
module.exports = add;
That a
module returns a number in this sample, but in my real project I use that as a config object that is changed from time to time manually.
var a = 1;
module.exports = a;
The test for the add
function looks like this:
describe('add', () => {
it('should add the mock number 1 to 2', () => {
jest.setMock('./a', 1);
const add = require('./add');
expect(add(2)).toBe(3);
});
it('should add the mock number 2 to 2', () => {
jest.setMock('./a', 2);
const add = require('./add');
expect(add(2)).toBe(4);
});
});
First test passes, The second test fails because it inherits from the first mock. Is there any way to mock the a
module multiple times?
I would like a solution that doesn't imply refactoring the add
function and instead focus on mocking that module multiple times. (in my real project that is a config file)
You can play around with the code here: https://repl.it/@adyz/NocturnalBadComma
You can use jest. mock (line 4) to mock the lang dependency. In the example above, the mock module has a current field which is set to a mock function. You want to test both branches of hello, so you use mockReturnValueOnce to make the mock function return "GL" in the first invocation, and "EN" in the second one.
To mock a function's return value in Jest, you first need to import all named exports from a module, then use mockReturnValue on the imported function. You can use the * as <alias> inside an import statement to import all named exports. Then, you need to chain mockReturnValue off of jest. fn .
The Jest library provides the jest. fn() function for creating a “mock” function. An optional implementation function may be passed to jest. fn() to define the mock function's behavior and return value.
Add
beforeEach(() => {
jest.resetModules();
});
Final tests
describe('add', () => {
beforeEach(() => {
jest.resetModules();
});
it('should add the mock number 5 to 2', () => {
jest.setMock('./a', 5);
const add = require('./add');
expect(add(2)).toBe(7);
});
it('should add the mock number 2 to 2', () => {
jest.setMock('./a', 2);
const add = require('./add');
expect(add(2)).toBe(4);
});
});
Demo: https://repl.it/repls/TrustingBelatedProprietarysoftware
To add to @Gigi's solution, I created another example, using jest.mock:
In the file multiplier.ts, multiplier
is the exported function we want to test:
// file: multiplier.ts
import {getNumber} from './get-number'
const multiplier = (num:number) => num * getNumber()
export {multiplier}
In the file get-number.ts, getNumber
is the module we want to mock:
// file: get-number.ts
const getNumber = () => 2
export {getNumber}
Here is the test:
// file: multiplier.test.ts
// import { multiplier } from "./multiplier" // <-- this will not work
describe("[multiplier]", () => {
beforeEach(() => {
jest.resetModules()
})
it('should mock getNumber so that getNumber return 3', () => {
const mockReturn = 3
jest.mock( './get-number', () => (
{ getNumber: jest.fn(()=>mockReturn) }
))
const { multiplier } = require('./multiplier')
expect(multiplier(2)).toBe(6)
})
it('should mock getNumber so that getNumber return 4', () => {
const mockReturn = 4
jest.mock( './get-number', () => (
{ getNumber: jest.fn(()=>mockReturn) }
))
const { multiplier } = require('./multiplier')
expect(multiplier(2)).toBe(8)
})
it('should mock getNumber so that getNumber return 5', () => {
const mockReturn = 5
jest.mock( './get-number', () => (
{ getNumber: jest.fn(()=>mockReturn) }
))
const { multiplier } = require('./multiplier')
expect(multiplier(2)).toBe(10)
})
})
Note: for this to work, we need to use require to import multiplier.ts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With