-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError: _MyClass2.default is not a constructor using jest.mock(path, factory) on ES6 class import #5023
Comments
EDIT: Ignore last post, this diff makes your tests pass: diff --git i/src/es6-classes-demo/sound-player-consumer-factory-mock.test.js w/src/es6-classes-demo/sound-player-consumer-factory-mock.test.js
index 6554483..c2c548f 100644
--- i/src/es6-classes-demo/sound-player-consumer-factory-mock.test.js
+++ w/src/es6-classes-demo/sound-player-consumer-factory-mock.test.js
@@ -1,13 +1,14 @@
import SoundPlayerConsumer from './sound-player-consumer';
import SoundPlayer from './sound-player';
+let mockPlaySoundFile = jest.fn();
// These tests all fail when SoundPlayerConsumer calls the constructor of SoundPlayer,
// throwing TypeError: _soundPlayer2.default is not a constructor
jest.mock('./sound-player', () => {
- return {
- playSoundFile: jest.fn()
- };
+ return jest.fn().mockImplementation(() => ({
+ playSoundFile: mockPlaySoundFile
+ }));
});
it('The consumer should be able to call new() on SoundPlayer', () => {
@@ -24,5 +25,5 @@ it('We can check if the consumer called a method on the class instance', () => {
const soundPlayerConsumer = new SoundPlayerConsumer();
const coolSoundFileName = 'song.mp3';
soundPlayerConsumer.playSomethingCool();
- expect(SoundPlayer.playSoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
+ expect(mockPlaySoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
}); |
PR welcome for docs update! |
Thanks Simen! Will try this out and create a docs PR in the next couple of weeks. |
@SimenB I tried it and it works. I'd like to understand what's going on before submitting a docs PR. Can you say a few words about why this works, and/or point me to the relevant jest source code? |
You returned an object, which you tried to Does that make sense? |
Ah, I see. Yes, that helps a lot, thanks! So then the factory function must be a HOF. I'll clarify that in the docs PR. (Edit: working on that PR!) For anyone reading this before the docs are updated, here's more info on StackOverflow: |
For anyone reading this comment, I have setup a GitHub repository to test mocking modules and classes. It is based on the principles described in the Stack Overflow post mentioned above, but it covers both default and named exports. |
None of the above worked for me. I'm using React / Redux with ES6, and Jest && Enzyme for testing. In my case, I had to mock a node module. In the file I'm using, and writing a test for, I'm importing the node modules as default:
So I needed to mock it as a default since I kept getting the error
In my case, I just needed to override the function and make it return an empty object. If you need to call a function on that node module, you'll do the following:
Hopefully this helps someone :) |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Do you want to request a feature or report a bug?
It's not clear from the docs whether this is expected behavior or not. So at a minimum it's a documentation bug and code feature request.
I'd be happy to submit a PR if this is confirmed to be a real issue.
What is the current behavior?
Assuming the following scenario: An ES6 class (
MyClassConsumer
) is being tested with Jest. That class imports another ES6 class (MyClass
) and callsnew MyClass()
to create a new instance/object of that class. In the test forMyClassConsumer
,MyClass
is mocked since that class is not to be tested. See the demo repo for a full example, or see sample code at the bottom of this issue.When mocking es6 classes using
jest.mock('./my-class', ()=>{return {myFunc: jest.fn()}})
, the mock does not function correctly. This results in the error TypeError: _MyClass2.default is not a constructor in fileMyClassConsumer
on the line where it callsnew MyClass()
.There is nothing that can be passed as the module factory parameter (2nd parameter to
jest.mock()
) that will correct this error.There is a workaround, which is to use jest.mock() and then separately call
MyClass.mockImplementation(...)
.If the current behavior is a bug, please provide the steps to reproduce and
either a repl.it demo through https://repl.it/languages/jest or a minimal
repository on GitHub that we can
yarn install
andyarn test
.Repo demonstrating the issue is here:
https://github.com/jonathan-stone/jest-es6-classes-demo
Used create-react-app to generate a base React app, and added demo files into src/es6-classes-demo.
What is the expected behavior?
Documentation expected behavior:
The docs specifically mention how to mock ES6 class imports, with at least one example.
Code expected behavior:
Passing a module factory function into
jest.mock()
allows files that import the mocked class to callnew
on it without throwing an error.Please provide your exact Jest configuration and mention your Jest, node,
yarn/npm version and operating system.
OS: MacOS Sierra 10.12.6
Jest version: 21.2.1
Node version: 8.9.0
NPM version: 5.5.1
Jest configuration: Various. Here's an example which is confirmed to repro the issue:
In demo repo, Jest config is provided by react-scripts.
Create-react-app version: 1.4.3
(Demo repo uses jest version 20.0.4 since that's what CRA created. But same issue occurs with latest Jest.)
Example code:
Class being mocked -
sound-player.js
:Class being tested -
sound-player-consumer.js
Test that generates the error:
Test Output
FAIL src/es6-classes-demo/sound-player-consumer-factory-mock.test.js
● The consumer should be able to call new() on SoundPlayer
● We can check if the consumer called the class constructor
● We can check if the consumer called a method on the class instance
The text was updated successfully, but these errors were encountered: