Developer
Developer

Reputation: 26253

Jest Unit test, mock implementation of IF condition within function for complete code coverage

I have a API script in a file

const ApiCall = {
  fetchData: async (url) => {
    const result = await fetch(url);
    if (!result.ok) {
      const body = await result.text(); // uncovered line
      throw new Error(`Error fetching ${url}: ${result.status}  ${result.statusText} - ${body}`); // uncovered line
    }
    return result.json();
  },
};

export default ApiCall;

When I mock the call, I have two uncovered lines in code coverage.

Any idea how can I make them cover as well.

Here is what I have tried so far which is not working

  it('test', async () => {   
    ApiCall.fetchData = jest.fn();
    ApiCall.fetchData.result = { ok: false };
  });

I am kind of new into Jest, so any help would be great.

Upvotes: 1

Views: 8521

Answers (2)

sebastianf182
sebastianf182

Reputation: 9978

Assuming that what you want to test is the ApiCall then you would need to mock fetch. You are mocking the entire ApiCall so those lines will never execute.

Also, you have an issue, because if you find an error or promise rejection, the json() won't be available so that line will trigger an error.

Try this (haven't test it):

it('test error', (done) => {  
let promise = Promise.reject(new Error("test"));
global.fetch = jest.fn(() => promise); //You might need to store the original fetch before swapping this
    ApiCall.fetchData()
.catch(err => );
   expect(err.message).toEqual("test");
   done();
  });

it('test OK', (done) => {  
let promise = Promise.resolve({
   json: jest.fn(() => {data: "data"})
});
global.fetch = jest.fn(() => promise); 
    ApiCall.fetchData()
.then(response => );
   expect(response.data).toEqual("data");
   done();
  });

That probably won't work right away but hopefully you will get the idea. In this case, you already are working with a promise so see that I added the done() callback in the test, so you can tell jest you finished processing. There is another way to also make jest wait for the promise which is something like "return promise.then()".

Plese post back

Upvotes: 0

awaruaboy
awaruaboy

Reputation: 66

You need to provide a stubb response in your test spec so that the if statement is triggered. https://www.npmjs.com/package/jest-fetch-mock will allow you to do just that. The example on their npm page should give you what you need https://www.npmjs.com/package/jest-fetch-mock#example-1---mocking-all-fetches

Basically the result is stored in state(redux) and is called from there. jest-fetch-mock overrides your api call/route and returns the stored result in redux all within the framework.

Upvotes: 0

Related Questions