Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service mocked with Jest causes "The module factory of jest.mock() is not allowed to reference any out-of-scope variables" error

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.

like image 437
Ria Avatar asked Jun 20 '17 09:06

Ria


People also ask

Can I mock a variable in Jest?

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.

How do you mock component in Jest?

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.

What is auto mocking in Jest?

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.


1 Answers

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  }); 
like image 147
maxletou Avatar answered Oct 18 '22 14:10

maxletou