Jest: Jest doesn't work with modules that return higher order functions

Created on 24 May 2016  Â·  10Comments  Â·  Source: facebook/jest

Here is a simplified example of the problem I'm having:

// ./module1.js
export default () => () => {};

// ./module2.js
import module1 from './module1';

export default module1();

// ./__tests__/module2-test.js
jest.unmock('../module2');

import module2 from '../module2';

describe('module2', () => {
  it('should have umocked module1', () => {
    module2();
  });
});

This will result in the following error: TypeError: (0 , _module2.default) is not a function.

To solve this problem, all that is necessary is to unmock module1 by adding jest.unmock('../module1') before importing module2.

Is this intentional? I assumed that if you unmocked a module, Jest would recursively unmock its dependencies so that this type of error doesn't happen.

It feels weird to me to unmock module1 when it is never required inside module2-test.js. Is this the expected behavior? Is the developer expected to unmock the dependencies of the function being tested? If so, is this only for immediate dependencies (depth = 0)?

Most helpful comment

We are thinking of adding a recursive option to unmock, but yes, this is intentional at the moment. We'll probably add something like deepUnmock or jest.unmock('Foo', {transitive: true}).

All 10 comments

Recursive unmocking feels a little too automagical for me, TBH. Mocking is on a per-require basis.

I agree that recursive unmocking is definitely unnecessary. I think the problem here is something else: incompatibility with modules that return higher order functions.

I originally came across this issue when writing my own versions of React Native's NavigatorExperimental createStackReducer and createTabsReducer (module2 in my example above). I made a helper function called createSubReducer (module1 in my example above) that is a module that returns a higher order function.

While Jest knows to make a mock that returns a function when the module's default export is called, it doesn't know that that function itself returns another function. So when that final function in the chain gets called, the error shown above happens.

I know this sounds contrived but it's a real issue with testing modules that export higher order functions with Jest.

If I happened to release my version of createTabsReducer on npm and somebody used it in yet another reducer they made and wrote tests using Jest, he would run into the same error. But in this case he wouldn't know to unmock createSubReducer (module1 in my example above) because that's part of the module's internals.

We are thinking of adding a recursive option to unmock, but yes, this is intentional at the moment. We'll probably add something like deepUnmock or jest.unmock('Foo', {transitive: true}).

Awesome! Thanks @cpojer.

I'll just unmock the internal modules manually for now. Any idea when deepUnmock might be available?

EDIT: Also, might there be a solution implemented that handles modules that return higher order functions without using recursion?

No ETA but the feature already exists in Runtime.js for node modules. If you'd like to send a PR, I'd be happy to help you through it – it should be fairly easy :)

Feel free to message me on Facebook: fb.me/cpojer

Suffering the same issue. Look forward to this PR.

Im beginning to feel after a month of Jesting we are always struggling with mocks / auto-mocks more often then we ever. Never seemed to have mocking issues on competing libraries: mocha / ava.

maybe its our approach :-(

btw. this is mostly a React issue, as it has special cases for React classes but not functional components. See https://github.com/facebook/react/issues/6932

@andrewmclagan auto-mocking might not be right for you then. I recommend turning it off using "automock": false in the configuration.

We are disabling automocking in Jest 15 and I think we aren't going to change React to adapt to this, so I'm closing this issue. Jest 15 will be released sometime this week :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Secretmapper picture Secretmapper  Â·  3Comments

paularmstrong picture paularmstrong  Â·  3Comments

withinboredom picture withinboredom  Â·  3Comments

samzhang111 picture samzhang111  Â·  3Comments

Antho2407 picture Antho2407  Â·  3Comments