I'm trying to mock a call to a service but I'm struggeling with the following message: The module factory of jest.mock()
is not allowed to reference any out-of-scope variables.
I'm using babel with ES6 syntax, jest and enzyme.
I have a simple component called Vocabulary
which gets a list of VocabularyEntry
-Objects from a vocabularyService
and renders it.
import React from 'react'; import vocabularyService from '../services/vocabularyService'; export default class Vocabulary extends React.Component { render() { let rows = vocabularyService.vocabulary.map((v, i) => <tr key={i}> <td>{v.src}</td> <td>{v.target}</td> </tr> ); // render rows } }
The vocabularyServise
ist very simple:
import {VocabularyEntry} from '../model/VocabularyEntry'; class VocabularyService { constructor() { this.vocabulary = [new VocabularyEntry("a", "b")]; } } export default new VocabularyService();`
Now I want to mock the vocabularyService
in a test:
import {shallow} from 'enzyme'; import React from 'react'; import Vocabulary from "../../../src/components/Vocabulary "; import {VocabularyEntry} from '../../../src/model/VocabularyEntry' jest.mock('../../../src/services/vocabularyService', () => ({ vocabulary: [new VocabularyEntry("a", "a1")] })); describe("Vocabulary tests", () => { test("renders the vocabulary", () => { let $component = shallow(<Vocabulary/>); // expect something });
});
Running the test causes an error: Vocabulary.spec.js: babel-plugin-jest-hoist: The module factory of jest.mock()
is not allowed to reference any out-of-scope variables. Invalid variable access: VocabularyEntry.
As far as I unterstood, I cannot use the VocabularyEntry because it is not declares (as jest moves the mock definition to the top of the file).
Can anyone please explain how I can fix this? I saw solutions which required the references insinde the mock-call but I do not understand how I can do this with a class file.
If you need to mock a global variable for all of your tests, you can use the setupFiles in your Jest config and point it to a file that mocks the necessary variables. This way, you will have the global variable mocked globally for all test suites.
To mock a React component, the most straightforward approach is to use the jest. mock function. You mock the file that exports the component and replace it with a custom implementation. Since a component is basically a function, the mock should also return a function.
With Jest's automatic mocks, we can mock classes or constructor functions easily. All methods are mocked with functions that return undefined . Then we can retrieve the mock by using mockedObject. mock. instances , which is an array.
You need to store your mocked component in a variable with a name prefixed by "mock". This solution is based on the Note at the end of the error message I was getting.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with
mock
are permitted.
import {shallow} from 'enzyme'; import React from 'react'; import Vocabulary from "../../../src/components/Vocabulary "; import {VocabularyEntry} from '../../../src/model/VocabularyEntry' const mockVocabulary = () => new VocabularyEntry("a", "a1"); jest.mock('../../../src/services/vocabularyService', () => ({ default: mockVocabulary })); describe("Vocabulary tests", () => { test("renders the vocabulary", () => { let $component = shallow(<Vocabulary/>); // expect something });
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