1

I'm facing a problem I'm not able to resolve on my own, maybe some of you faced the same problem.

Let me show you what I'm trying to do, here is the mock:

let mockConfig = {name: 'dude'};
jest.mock('../../../configManager', () => mockConfig);

configManager is a dependency of the function I'm trying to test.

It works well but I want to change the returning object of configManager in another test so the tested function behaves differently.

Let me show you, here is the function I'm testing:

const config = require('../../../configManager');

module.exports = () => {
if (config.name === 'dude') {
  do stuff;
}

if (config.name === 'dudette') {
  do something else;
}

So, typically, I want to change the config.name to 'dudette' to be able to test the second part of my function.

Naturally, when I want to do this with an imported function, I just do:

let mockJsonQueryResult = { value: 'stuff' };
jest.mock('json-query', () => jest.fn(() => mockJsonQueryResult));

and then in the test, I directly set another value to mockJsonQueryResult:

mockJsonQueryResult = { value: 'hotterStuff' };

But I don't find any way of doing this with a dependency that returns an object, with a dependency returning a function, no problem.

Is there even any way of doing this?

Thanks in advance!

Edit: this is not the same as how to change jest mock function return value in each test? as @Dor Shinar suggested because his problem is to mock a function, even if it is inside a returning object it is still a function, I just want to change a value inside the returned object.

  • Possible duplicate of [how to change jest mock function return value in each test?](https://stackoverflow.com/questions/45758366/how-to-change-jest-mock-function-return-value-in-each-test) – Dor Shinar Jun 06 '19 at 16:13

2 Answers2

0

So, I found a solution I'm not completely satisfied with but it works:

I simply set the original full object and then for my tests, change the value of specific properties by setting them directly before calling the function I want to test.

example:

let mockConfig = { person: { name: 'dude', origin: {country: 'France'} } };
jest.mock('../../../configManager', () => mockConfig);


mockConfig.person = {};
mockConfig.person.name = 'dudette';
0

You don't need to mock the module at all.

If your module export is just an object with property values then just change the properties as needed.

Here is a simple working example to demonstrate:

configManager.js

module.exports = {
  name: 'original'
}

code.js

const config = require('./configManager');

module.exports = () => `name: ${config.name}`;

code.test.js

const config = require('./configManager');
const func = require('./code');

test('func', () => {
  expect(func()).toBe('name: original');  // Success!

  config.name = 'dude';
  expect(func()).toBe('name: dude');  // Success!

  config.name = 'dudette';
  expect(func()).toBe('name: dudette');  // Success!
})

Details

A module binding can't be directly changed to something else:

const config = require('./configManager');
config = { name: 'mock' };  // <= this doesn't work

...but you can change the properties of an object representing a module binding:

const config = require('./configManager');
config.name = 'mock';  // <= this works!

...and any code using the module will automatically see the changes.

Brian Adams
  • 43,011
  • 9
  • 113
  • 111