Mock.mockImplementation() not working

2020-07-01 05:11发布

问题:

I have a service class

Service.js

class Service {
}
export default new Service();

And I am trying to provide a mock implementation for this. If I use something like this:

jest.mock('./Service', () => { ... my mock stuff });

It works fine, however I'm not able to access any variables declared outside of the mock, which is a bit limiting as I'd like to reconfigure what the mock returns, etc.

I tried this (inspired by this other StackOverflow article: Service mocked with Jest causes "The module factory of jest.mock() is not allowed to reference any out-of-scope variables" error)

import service from './Service';

jest.mock('./Service', () => jest.fn);

service.mockImplementation(() => {
    return { ... mock stuff }
);

Unfortunately when I am trying to run this, I get the below error:

TypeError: _Service2.default.mockImplementation is not a function

回答1:

The mock is equal to jest.fn. You need to call jest.fn to create a mocked function.

So this:

jest.mock('./Service', () => jest.fn);

Should be:

jest.mock('./Service', () => jest.fn());


回答2:

I had same problem as @Janos, the other answers didn't help either. You could do two things :

1/ If you need to mock only a function from Service, in your test file:

import service from './Service';

jest.mock('./Service', () => jest.fn());

service.yourFunction = jest.fn(() => { /*your mock*/ })

2/ If you need to mock the entire Module:

Say your service.js is in javascript/utils, create a javascript/utils/__mocks__ and inside it create a service.js file, you can then mock the entire class in this file, eg:

const myObj = {foo: "bar"}

const myFunction1 = jest.fn(() => { return Promise.resolve(myObj) })

const  myFunction2 = ...

module.exports = {
  myFunction1,
  myFunction2
}

then in your test file you just add :

jest.mock('./javascript/utils/service')

functions exported from the mockfile will be then hit through your test file execution



回答3:

ran into similar issues and resolved it by using .mockImplementationOnce

jest.mock('./Service', () => jest.fn()
  .mockImplementationOnce(() => {
    return { ... mock stuff }
  })
  .mockImplementationOnce(() => {
   return { ... mock other stuff }
  })
);

now when you run another test it will return the second mock object.



回答4:

You need to store your mocked component in a variable with a name prefixed by "mock" and make sure you return an object with a default property as you import your Service from the default in your "main.js" file.

// Service.js
class Service {
}
export default new Service();

// main.test.js (main.js contains "import Service from './Service';")

const mockService = () => jest.fn();

jest.mock('./Service', () => {
    return {
        default: mockService
    }
});


回答5:

I had similar problem, and the cause was that ".spec.js" file had an

import jest from "jest-mock";

After removing this line, it worked.



标签: jestjs