Skip to content
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

ReferenceError: Cannot access 'myMock' before initialization even though the rule is respected #10996

Closed
Sufiane opened this issue Jan 3, 2021 · 11 comments

Comments

@Sufiane
Copy link

Sufiane commented Jan 3, 2021

🐛 Bug Report

I'm getting the error:

ReferenceError: Cannot access 'myMock' before initialization

Even though i respected jest documentation about the hoisting: A limitation with the factory parameter is that, since calls to jest.mock() are hoisted to the top of the file, it's not possible to first define a variable and then use it in the factory. An exception is made for variables that start with the word 'mock'.

what i'm doing:

import MyClass from './my_class';
import * as anotherClass from './another_class';

const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();
jest.mock('./my_class', () => {
  return {
    default: {
      staticMethod: jest.fn().mockReturnValue(
        {
          method1: mockMethod1,
          method2: mockMethod2,
        })
    }
  }
});

As you can see, i'm mocking a singleton class.
The static method (here: staticMethod) is the entry point of my class.

To Reproduce

Steps to reproduce the behavior:
Having a singleton class like so:

class MyClass {
  private instance

  private constructor(){ /* constructor thing */}

  static staticMethod(){
     if MyClass.instance { return MyClass.instance}

     /* do constructor etc....*/
     }
}
```�

And i'm using this in the file I actually want to test:

```typescript
import MyClass from '/path/to/myClass'

const myClass = MyClass.staticMethod()

/* business logic goes here */

About the test file, you can see what i'm doing above.

Expected behavior

Not throwing ReferenceError: Cannot access 'myMock' before initialization when the rule about mock variable starting with mockis respected.

Link to repl or repo (highly encouraged)

envinfo

  System:
    OS: macOS 10.15.5
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
  Binaries:
    Node: 12.18.4 - ~/.nvm/versions/node/v12.18.4/bin/node
    npm: 6.14.6 - ~/.nvm/versions/node/v12.18.4/bin/npm
  npmPackages:
    jest: ^26.6.3 => 26.6.3 

Thanks in advance for any help !

@zaverden
Copy link

zaverden commented Feb 1, 2021

As I can see the error message tells you about variable myMock but your code example does not include myMock variable definition anywhere. I can think about 2 cases why it works this way

  1. the error is from another test file. so you can search your project for myMock and fix it there
  2. jest has failed to invalidate its cache and uses old transpiled files. In this case check this SO answer to clear jest cache

@SimenB
Copy link
Member

SimenB commented Feb 1, 2021

There is nothing called myMock in your reproduction. It also doesn't contain another_class. Please provide full reproductions (preferably a repository we can clone and run).

https://stackoverflow.com/help/minimal-reproducible-example

@kylegoetz
Copy link

kylegoetz commented Feb 1, 2021

This is happening to me, too:

index.test.ts:

const mockUseAuthToken = jest.fn()

jest.mock('../../../src/hooks/use-auth-token', () => ({
	useAuthToken: mockUseAuthToken,
}))

Jest output:

ReferenceError: Cannot access 'mockUseAuthToken' before initialization

       8 | 
       9 | jest.mock('../../../src/hooks/use-auth-token', () => ({

package.json:

"jest": "26.6.3"

This was working before upgrading Jest. Previously was on `26.0.1`.

@amitnsky
Copy link

amitnsky commented Feb 3, 2021

You may use this:

import { X } from 'path/to/module'

jest.mock('path/to/module', () => ({
    X: jest.fn()
}));

in your test block::

expect(X).toHaveBeenCalled()

@kylegoetz
Copy link

@amitnsky any suggestion then for TypeScript complaining that property mockImplementation does not exist on type (params) => returnVal?

@SimenB
Copy link
Member

SimenB commented Feb 5, 2021

Instead of saying "+1", please provide reproductions.

Questions about TS is out of scope for this issue (and this repo if you use @types/jest)

@amitnsky
Copy link

amitnsky commented Feb 5, 2021

@kylegoetz can you share code pls so that i can check.

@drex44
Copy link

drex44 commented Feb 18, 2021

You may use this:

import { X } from 'path/to/module'

jest.mock('path/to/module', () => ({
    X: jest.fn()
}));

in your test block::

expect(X).toHaveBeenCalled()

@amitnsky thank you 🙇

@SimenB
Copy link
Member

SimenB commented Feb 18, 2021

No reproduction has been provided, so I'll close this.

Feel free to open up a new issue with a minimal reproduction if anybody has one

@SimenB SimenB closed this as completed Feb 18, 2021
@overflowz
Copy link

overflowz commented Feb 26, 2021

Bump, need to reopen this. I have a function, which returns another function(s) that I'd like to mock. With the solution provided, it's not really possible. re-mocking is not possible as well. Here's the minimal code to reproduce:

const mock = jest.fn();

jest.mock('module', () => ({
  fn: mock,
}));

output:

ReferenceError: Cannot access 'mock' before initialization

the module looks like this:

export default (...args) => {
  // some code
  
  return {
    foo: () => ...,
    bar: () => ..., // <-- I want to mock this.
  };
};

I tried remocking it in beforeEach, but does not seem to work, because module is imported this way:

import module from 'module';

const { bar } = module(...);

EDIT: this is only affected when the destructuration happens in a global scope (root level), not affected if it's inside a function.

@SimenB
Copy link
Member

SimenB commented Feb 26, 2021

Feel free to open up a new issue with a minimal reproduction if anybody has one

Note it should also be complete not snippets. https://stackoverflow.com/help/minimal-reproducible-example is a great text explaining what goes into a good reproduction case for a bug report 🙂

@jestjs jestjs locked as spam and limited conversation to collaborators Feb 26, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants