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

前端 未结 5 1678
南方客
南方客 2020-12-08 18:53

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 a

相关标签:
5条回答
  • 2020-12-08 19:19

    The problem is that all jest.mock will be hoisted to the top of actual code block at compile time, which in this case is the top of the file. At this point VocabularyEntry is not imported. You could either put the mock in a beforeAll block in your test or use jest.mock like this:

    import {shallow} from 'enzyme';
    import React from 'react';
    import Vocabulary from "../../../src/components/Vocabulary ";
    import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
    import vocabularyService from '../../../src/services/vocabularyService'
    
    jest.mock('../../../src/services/vocabularyService', () => jest.fn())
    
    vocabularyService.mockImplementation(() => ({
      vocabulary: [new VocabularyEntry("a", "a1")]
    }))
    

    This will first mock the module with a simple spy and after all stuff is imported it sets the real implementation of the mock.

    0 讨论(0)
  • 2020-12-08 19:20

    If you are getting similar error when upgrading to newer Jest [19 to 21 in my case], you can try changing jest.mock to jest.doMock.

    Found this here – https://github.com/facebook/jest/commit/6a8c7fb874790ded06f4790fdb33d8416a7284c8

    0 讨论(0)
  • 2020-12-08 19:22
    jest.mock("../../../src/services/vocabularyService", () => {
      // eslint-disable-next-line global-require
      const VocabularyEntry = require("../../../src/model/VocabularyEntry");
    
      return {
        vocabulary: [new VocabularyEntry("a", "a1")]
      };
    });
    

    I think it should work with dynamic imports as well instead of require but didn't manage to make it work.

    0 讨论(0)
  • 2020-12-08 19:25

    In my case this issue started after I was upgrade my react-native project to v0.61 using react-native-git-upgrade.

    After I have tried everything I could. I decide to clean the project and all my tests back to work.

    # react-native-clean-project
    

    However watch out when running the react-native-clean-project, it can wipe out all ios and android folder including native code, so just answer N when prompted. In my case I just selected wipe node_modules folder.

    0 讨论(0)
  • 2020-12-08 19:30

    This is how I would solve it for your code.

    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
    
    });
    
    0 讨论(0)
提交回复
热议问题