Reputation: 338
I have a generic FetchService in React/TS like this:
/* Generic Fetch Service */
const FetchService = {
call: async (url:string) => {
try {
return await fetch(url)
.then((res) => res.json())
.then((data) => { data.response});
} catch (e) {
throw Error(e);
}
}
}
export default FetchService
and a test written like this:
import FetchService from "../../services/Fetch.service";
it("should call Fetch Service", async () => {
const val = { json: async () => [{ data: { response: "aaa" } }] };
window.fetch = jest.fn().mockImplementationOnce((url) => {
if (url === "localhost") {
return Promise.resolve(val);
}
});
const data = await FetchService.call("localhost");
expect(data).toBe(undefined);
});
It does succeed to cover the success , but it returns 'undefined', not the data I mocked at response on my test. If I put a console.log in my service, at the data.response, it will log the 'aaa', from the test.
What Im doing wrong?
I´ve tried all the answers here in StackOverflow, as also some tutorials and nothing worked.
Using Jest Docs also didn't helped much.
Anyone could help me out?
Thanks.
Edit:
Solved thanks to the two answers here
/* Generic Fetch Service */
const FetchService = {
call: async (url: string) => {
try {
const response = await fetch(url);
const data = await response.json();
console.log(data.response, "data111");
return data.response;
} catch (err) {
throw err;
}
},
};
export default FetchService;
and at the test:
const val = {
json: async () => {
return { response: "aaa" };
},
};
it("should call Fetch Service", async () => {
window.fetch = jest.fn().mockImplementationOnce((url) => {
if (url === "localhost") {
return val;
}
});
const data = await FetchService.call("localhost");
expect(data).toBe("aaa");
});
Upvotes: 1
Views: 2108
Reputation: 189
You're attempting to use "async" while promise chaining, which is not good practice. You have two ways you can handle this.
// with async await
const FetchService = {
call: async (url:string) => {
try {
const response = await fetch(url);
const data = await response.json();
return data.response;
} catch (err) {
throw err;
}
}
}
//without async await (Promise chaining method)
const FetchService = {
call: (url:string) => {
return fetch(url)
.then((res) => res.json())
.then((data) => data.response)
.catch(err => {
throw err
})
}
}
export default FetchService
Upvotes: 1
Reputation: 1932
You are returning [{ data: { response: "aaa" } }]
in your mock and then getting [{ data: { response: "aaa" } }].response
in your FetchService (which is undefined).
Depending on what you want, you could modify the expected data in the FetchService, or provide a different sample data in your mock:
const FetchService = {
call: (url:string) => {
return fetch(url)
.then((res) => res.json())
.then((obj) => { obj[0].data.response});
}
}
Upvotes: 2