22

I have a mock object that I am using to mock react-native:

const MyMock = {
    MockA: {
        methodA: jest.genMockFn()
    },
    MockB: {
        ObjectB: {
            methodA: jest.genMockFn(),
            methodB: jest.genMockFn(),
        }
    }
};


jest.mock('react-native', () => {
    return MyMock;
});

I am declaring the object outside of jest.mock because I also need it later on in my tests:

describe('MyClass', () => {
     beforeEach(() => {
         MyMock.MockB.ObjectB.methodA.mockClear();
         MyMock.MockB.ObjectB.methodB.mockClear();
     });
     //some other code

I get this error:

The module factory of jest.mock() is not allowed to reference any out-of-scope variables.

The problem is that I declare MyMock outside of jest.mock. But I have no choice as far as I can see.

So how can I make the code work while keeping MyMock outside of jest.mock?

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
bsky
  • 19,326
  • 49
  • 155
  • 270

1 Answers1

53

I hadn't read the error message fully. On the last line(slightly obscured) there is this:

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.

So when I changed MyMock to for instance mockMyMock, it worked.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
bsky
  • 19,326
  • 49
  • 155
  • 270
  • This is very useful! Prefixing variables with `mock` reduces code duplication while maintaining clear scopes of what the mocked item should be able to access. – Arian Acosta Nov 02 '18 at 18:50
  • Appreciate the follow up comment. Any chance you happen to know where in the Jest documentation this naming convention is noted? – cheshireoctopus Oct 16 '19 at 16:56
  • 1
    Not sure about the docs, but the error message I got was quite good. So for import `const {level} = require('test-utils/mocks')` and mock `jest.mock('level', () => level)` the error was: `The module factory of jest.mock() is not allowed to reference any out-of-scope variables. Invalid variable access: ... Whitelisted objects: ... 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` (case insensitive) are permitted.` Prefixing with `mock` didn't help though. – watofundefined Jan 05 '20 at 20:16
  • 1
    This worked though: `jest.mock('level', () => require('test-utils/mocks').level)` – watofundefined Jan 05 '20 at 20:17
  • 2
    After prepending `mock` to the function name, I am getting the error 'Cannot read `undefined` of `functionName`'. Any idea why this might be happening? – darKnight Mar 11 '21 at 06:43