-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
how to test api calls using fetch? #967
Comments
Try setting |
@gaearon you mean like below? tried that no difference ... |
By the way I noticed you don't return Promise from the test. The runner can't know to wait for the promise to finish in this case. Have you tried returning Promise or using async await? See the async tutorial. it("ack", async function () {
const response = await Api.ack('foo', 'bar');
console.log(response);
expect(response.Id).toBe(1);
}); |
@gaearon you rock dude, thanks so much :) Api.test.js
results in :
can this be considered as good practice for testing promises returned by fetch in jest? |
BTW with the same mockImplementation as above, below now prints the
|
The test is likely passing because it has already finished executing, and so even throwing can't influence that particular test.
Sounds reasonable to me. |
Another way of testing API calls is node-fetch + nock. That way you can also test if your API calls are using expected HTTP methods, sending the expected body etc. Tests might also be slightly easier to read. |
Going to close since this is a usage question and not something we could/need to fix. |
I stumbled upon this post after burning hours trying to unit test fetch requests. All the mock fetch modules I could find on NPM were overly complex or required too much setup time, so I created fetch-reply-with. It simply adds a require('fetch-reply-with'); // <- fetch is now globally available within the node environment
// add a fetch reply for GET http://www.orcascan.com
fetch('http://www.orcascan.com', {
// regular fetch option
method: 'GET',
// add reply for this fetch
replyWith: {
status: 200,
body: 'Bulk Barcode Scanning app',
headers: {
'Content-Type': 'text/html'
}
}
})
.then(function(res) {
// handle the response within the first then
// as suggested by https://github.com/kevmarchant
});
// or at some point in the future
fetch('http://www.orcascan.com').then(function(res){
return res.text();
})
.then(function(text){
// text now equals Bulk Barcode Scanning app
}); Hope it helps the next frustrated developer! |
For people passing by, simplest working solution: function mockFetch(data) {
return jest.fn().mockImplementation(() =>
Promise.resolve({
ok: true,
json: () => data
})
);
}
test('fetchPerson()', async () => {
fetch = mockFetch(someJson); // or window.fetch
const person = await fetchPerson('whatever id');
expect(person).toEqual(someJson);
// Make sure fetch has been called exactly once
expect(fetch).toHaveBeenCalledTimes(1);
}); when testing this simple function: function fetchPerson(id) {
const response = await fetch(`${BASE_URL}/people/${id}`);
if (!response.ok) throw new Error(response.statusText);
const data = await response.json();
// Some operations on data if needed...
return person;
} Jest configuration: // File jest.setup.js
import 'whatwg-fetch'; // File jest.config.js
module.exports = {
setupFiles: ['./jest.setup.js'],
}; (because Jest uses Node.js and Node.js does not come with fetch => specific to web browsers) Real life simple example: https://github.com/tkrotoff/MarvelHeroes |
|
I'm having a hard time understanding below behaviour and would appreciate any help to pointing me into the right direction.
I have a generic class for my api calls:
in my Api.test.js I have a following code
regardless of what I set the response.Id in
Promise.resolve({ok: true, Id: '123'})
expect(response.Id).toBe(1)
orexpect(response.Id).toBe('abc')
always passThe text was updated successfully, but these errors were encountered: