I have seen questions referring to the mocking of default exports with jest around here, but I don't think this has already been asked:
When mocking the default export of a dependency of a module that is being tested, the tests suite fails to run if the module imports the dependency with the ES6 import statement, stating TypeError: (0 , _dependency.default) is not a function
It succeeds, however, if the module uses a require().default
call instead.
In my understanding, import module from location
directly translates to const module = require(location).default
, so I am very confused why this is happening. I'd rather keep my code style consistent and not use the require
call in the original module.
Is there a way to do it?
Test file with mock:
import './modules.js';
import dependency from './dependency';
jest.mock('./dependency', () => {
return {
default: jest.fn()
};
});
// This is what I would eventually like to call
it('calls the mocked function', () => {
expect(dependency).toHaveBeenCalled();
});
Dependency.js
export default () => console.log('do something');
module.js (not working)
import dependency from './dependency.js';
dependency();
module.js (working)
const dependency = require('./dependency.js').default;
dependency();
In order to successfully mock a module with a default export, we need to return an object that contains a property for __esModule: true and then a property for the default export. This helps Jest correctly mock an ES6 module that uses a default export. expect(method1()). toBe('You have called a mocked method 1!
To mock an exported const in Jest, we can use the jest. mock method. For instance, we write: const mockTrue = { ENABLED: true }; const mockFalse = { ENABLED: false }; describe('allowThrough', () => { beforeEach(() => { jest.
To mock an imported function with Jest we use the jest. mock() function. jest. mock() is called with one required argument - the import path of the module we're mocking.
Using with ES module imports But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist jest. mock calls to the top of the module (before any imports).
You can use either es6 import
or require js
to import your js files in your jest tests.
When using es6 import
you should know that jest is trying to resolve all the dependencies and also calls the constructor for the class that you are importing. During this step, you cannot mock it. The dependency has to be successfully resolved, and then you can proceed with mocks.
I should also add that as can be seen here jest by default hoists any jest.mocks to the top of the file so the order in which you place your imports does not really matter.
Your problem though is different. Your mock function assumes that you have included your js file using require js
.
jest.mock('./dependecy', () => {
return {
default: jest.fn()
};
});
When you import a file using require js
, this is the structure it has:
So assuming I have imported my class called "Test" using require js
, and it has method called "doSomething" I could call it in my test by doing something like:
const test = require('../Test');
test.default.doSomething();
When importing it using es6 import
, you should do it differently though. Using the same example:
import Test from '../Test';
Test.doSomething();
EDIT: If you want to use es6 import
change your mock function to:
jest.mock('./dependecy', () => jest.fn());
Have you tried something like this? I was dealing with the default export mocking for months until I found this.
jest.mock('./dependency', () => () => jest.fn());
The idea behind this line is that you are exporting a module that is a function. So you need to let Jest knows that it has to mock all your ./dependency
file as a function, that returns a jest.fn()
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