Javid Asgarov
Javid Asgarov

Reputation: 1532

Jest - how to mock a method within a function

I have an ES6 class A, that I need to test, the only thing I want to change is the implementation of one method, and all the other things to remain as they are.

First, I wanted manually to create a mock class like "myMock extends A" where I would change that method and use it for tests, but there were some problems.

Anyway, is there another way with jest to specify replacement of a specific method within a class?

What I tried to do now is following:

jest.mock("../myclass", () => {
return jest.fn().mockImplementation(() => {
    return {
        loadPopularItems: jest.fn(() => new Promise((resolve): void => 
           resolve()))
    };
  });
 });

This now gives me an error that myclass is not a constructor:

TypeError: myclass`.default is not a constructor

All I want to do is remove some async method from there, that makes HTTP requests.

Upvotes: 2

Views: 3486

Answers (1)

WickyNilliams
WickyNilliams

Reputation: 5298

You can stub out the method on the prototype in your test:

A.prototype.loadPopularItems = jest.fn()

Or you can use jest.spyOn to allow for easily resetting mocks:

jest.spyOn(A.prototype, "loadPopularItems");
jest.restoreAllMocks(); // avoids having to manually track mocks

Better yet, have your class accept whatever object/function makes HTTP requests as a constructor argument:

class A {
  constructor(http) {
    this.http = http;
  }

  loadPopularItems() {
     return this.http.fetchSomething();
  }
}

Then in your tests you can just pass a fake implementation:

const fakeHttp = {
  fetchSomething: jest.fn()
};

const instance = new A(fakeHttp);

This is generally the preferable over stubbing out methods.

Upvotes: 3

Related Questions