So I have been struggling with how to test dynamic imports generally and in this case, especially in jest, I have been reading a lot on the internet but did not find anything concrete, so I thought about bringing the question up to centralize a decent solution.
I have the following methods inside of a class
class MyClass {
successMethod() { ... }
errorMethod() { ... }
myMethod() {
return import('./myFile.js')
.then(() => this.successMethod())
.catch(() => this.errorMethod());
}
}
My question is:
How do you mock both Success and Failing promise cases for this dynamic import using Jest to make sure each method (successMethod
and errorMethod
) are called when resolving or failing respectively?.
I found jest.doMock
helps for mocking the resolved case but did not find a way to make the dynamic import fail by mocking it so the catch
case is uncovered.
Note: this is not a react application, this is a Vanilla JS project.
Jest is a JavaScript test runner, that is, a JavaScript library for creating, running, and structuring tests. Jest ships as an NPM package, you can install it in any JavaScript project. Jest is one of the most popular test runner these days, and the default choice for React projects.
Master dynamic imports to boost the speed of your apps If you've ever worked on a large React application, you know that the ability to dynamically render components and/or libraries can grant your application better performance.
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.
Dynamic import of modules It returns a promise and starts an asynchronous task to load the module. If the module was loaded successfully, then the promise resolves to the module content, otherwise, the promise rejects.
Prototype methods can be spied or mocked on either MyClass.prototype
or class instance. Module mocks and spy functions should be restored for each test in order for them to not affect each other.
let myClass;
beforeEach(() => {
jest.resetModules();
jest.restoreAllMocks();
myClass = new MyClass();
jest.spyOn(myClass, 'successMethod');
jest.spyOn(myClass, 'errorMethod');
});
jest.doMock
requires to import all affected modules after it was called. In order for dynamic import
to result in rejected promise, myFile
module should throw an error when evaluated. Since dynamic import
returns a promise, tests should be asynchronous.
it('...', async () => {
jest.mock('./myFile.js', () => 'value');
await expect(myClass.myMethod()).resolves.toEqual(/* return value from successMethod */);
expect(myClass.successMethod).toBeCalled();
expect(myClass.errorMethod).not.toBeCalled();
});
it('...', async () => {
jest.mock('./myFile.js', () => { throw new Error() });
await expect(myClass.myMethod()).rejects.toThrow(/* error message from errorMethod */);
expect(myClass.successMethod).not.toBeCalled();
expect(myClass.errorMethod).toBeCalled();
});
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