dx_over_dt
dx_over_dt

Reputation: 14318

Jest mocked implementation not being called outside of test function

I have a 3rd party module I need to mock (moment.js). I want to set the implementation to the default implementation before requiring the file I'm testing. The only function I'm mocking is the default export of the module, so I assign the prototype and static members to those of the actual implementation, as well.

season.js

import moment from 'moment';

export var currentSeason = getCurrentSeason();

export function currentSeasion() {
    const diff = moment().diff(/* ... */);
    // ...

    return /* a number */;
}

__tests__/season.js

import moment from 'moment';

jest.mock('moment');
const actualMoment = jest.requireActual('moment');

moment.mockImplementation((...args) => actualMoment(...args));
Object.assign(moment, actualMoment);

const { getCurrentSeason } = require('../season');

test('getCurrentSeason()', () => {
    moment.mockReturnValue(actualMoment(/* ... */));
    expect(getCurrentSeason()).toBe(1);
});

I confirmed via debugging that mockImpelementation() is being called correctly, and within the test, it's being called correctly too. However, in the initialization of currentSeason, moment() is returning undefined. When I stepped into the moment() mocked function, mockConfig.mockImpl is undefined.

Running expect(moment()).toBeUndefined() in the test file but outside of any test before the import of season.js runs the mock implementation, as well.

I can't for the life of me figure out why it's only not working in the initialization of currentSeason.

Upvotes: 1

Views: 1035

Answers (1)

dx_over_dt
dx_over_dt

Reputation: 14318

I don't know how useful this will be for anyone else, but my solution turned out to be to pull my mock code into it's own /__mocks__/moment.js file.

const actual = jest.requireActual('moment'),
    moment = jest.fn((...args) => actual(...args));

export default Object.assign(moment, actual);

Upvotes: 1

Related Questions