0
votes

I'm trying to test a module that imports from another that has a weird export structure.

I'm using javascript with node, and jest for testing.

This is basically the code structure for the exports and the tests.

// weirdModule.js
module.exports = ({param1, param2}) = {
  const weirdModuleFunction = async () => {
    return await someIrrelevantFunction(param1, param2);
  };
  return async () => {
      try {
        return await weirdModuleFunction();
      }
      catch (e) {
        throw e;
      }
    };
  }
}
// testThisModule.js
const _weirdModuleFunction = require('weirdModule.js');
const testThisFunction = () => {
   const weirdModuleFunction = _weirdModuleFunction({'abc',123});
   let someDataIWantToBeMockedFromWeirdModule = await weirdModuleFunction();

   const resultIWantToExpect = someDataIWantToBeMockedFromWeirdModule + ' someDataForExample';
   return resultIWantToExpect;
};
module.exports = { testThisFunction }
//testThisModule.test.js
const { testThisFunction } = require('testThisModule.js');

//jest mocks to return different values for weirdModule.js

it('should return some value from weirdModule + someData',()=>{
  //mockImplementation for weirdModule, maybe even mockImplementationOnce for successive testing
  expect(testThisFunction()).toEqual('whatIexpect1 someDataForExample');
  expect(testThisFunction()).toEqual('whatIexpectWithADifferentMockImplementation someDataForExample');
});

I'd like a solution that allows me to mock what weirdModule.js returns, and to also be able to mock it so it returns different values.

I have many tests for different branches, so I need to be able to change the mock return for weirdModule so I can have data that can be used across many tests, and some for some specific tests

I CANNOT change the structure of weirdModule (I didn't design it), and I CANNOT use anything other than jest, and I don't want to use manual mocks from __mocks__

I have managed to get it to work with only one return value, but I need to be able to change it to different values. It currently works like this:

jest.mock('weirdModule.js', () => () => {
  return jest.fn(() => {
    return 'whatIexpect1';
  });
}

How can I achieve this? I've been scratching my head for days trying to have jest play nice and not throw 'weirdModuleFunction is not a function' when trying to mock different values for different tests. Any help is appreciated.

1

1 Answers

0
votes

You need to capture weirdModule.js as a mock module in your test file. To do this, add these at the beginning of testThisModule.test.js

const weirdModule = require('weirdModule.js');
jest.mock('weirdModule.js');

Now you can mock the weird module however you want, like this:

it('should return some value from weirdModule + someData', async () => {
    //mockImplementation for weirdModule, maybe even mockImplementationOnce for successive testing
    weirdModule.mockImplementationOnce( () => {
        return () => {
            return 'whatIexpect1';
        };
    });
    expect(await testThisFunction()).toEqual('whatIexpect1 someDataForExample');
    weirdModule.mockImplementationOnce( () => {
        return () => {
            return 'whatIexpectWithADifferentMockImplementation';
        };
    });
    expect(await testThisFunction()).toEqual('whatIexpectWithADifferentMockImplementation someDataForExample');
});

Hope this helps!