我如何开玩笑地测试这个 api 中间件是否处理了 fetch 抛出的错误?
How do I test with jest whether this api middleware handles errors thrown by fetch?
我的 react/redux 应用程序中有以下 api 中间件,我开玩笑地对其进行单元测试。模块代码为:
// ./src/middleware/api.js
import fetch from 'isomorphic-fetch';
// Checks if the returned statuscode is in the successful range
const handleErrors = (response) => {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
};
export const get = (endpoint) => {
const options = { credentials: 'include', method: 'GET' };
return fetch(endpoint, options)
.then(handleErrors)
.then(response => response.json())
.catch(error => error.message);
};
测试是:
// ./src/middleware/__tests__/api.test.js
import fetch from 'isomorphic-fetch';
import { get } from '../api';
// Mock calls to fetch by the api middleware
// loads https://github.com/jefflau/jest-fetch-mock instead of fetch
jest.mock('isomorphic-fetch');
describe('api middleware', () => {
describe('get', () => {
it('should return the response on success', () => {
const expected = { data: ['data'], meta: {} };
const body = JSON.stringify(expected);
const init = { status: 200, statusText: 'OK' };
fetch.mockResponseOnce(body, init);
return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
});
it('should return the statusText for unsuccessful status codes', () => {
const expected = 'Unauthorized';
const body = JSON.stringify({ errors: ['You are not logged in'] });
const init = { status: 401, statusText: expected };
fetch.mockResponseOnce(body, init);
return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
});
// I have not been able to mock this so far
it('handles fetch errors', () => {
return get('doesnotexist').then(actual => expect(actual).toEqual(false));
});
});
});
在最后一个断言中,我想测试它是否捕获了 fetch 抛出的错误(例如,当没有网络连接时)。但我在测试时遇到了麻烦。我不确定我如何模拟提取中的错误然后对其进行测试。有谁知道我将如何模拟最后一个断言?
通过查看 jest-fetch-mock
的实现,它总是解决承诺,这意味着您的 fetch
永远不会去 catch
。所以你需要有一个 Promise.reject()
并且在你的测试中你需要做一些像 -
it('handles fetch errors', () => {
return get('doesnotexist')
.catch(error => expect(error).toEqual('some error'));
});
如果你给它一个无效的主体,它会触发你的 promise 的 catch 部分。
fetch.mockResponseOnce(null, init);
我的 react/redux 应用程序中有以下 api 中间件,我开玩笑地对其进行单元测试。模块代码为:
// ./src/middleware/api.js
import fetch from 'isomorphic-fetch';
// Checks if the returned statuscode is in the successful range
const handleErrors = (response) => {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
};
export const get = (endpoint) => {
const options = { credentials: 'include', method: 'GET' };
return fetch(endpoint, options)
.then(handleErrors)
.then(response => response.json())
.catch(error => error.message);
};
测试是:
// ./src/middleware/__tests__/api.test.js
import fetch from 'isomorphic-fetch';
import { get } from '../api';
// Mock calls to fetch by the api middleware
// loads https://github.com/jefflau/jest-fetch-mock instead of fetch
jest.mock('isomorphic-fetch');
describe('api middleware', () => {
describe('get', () => {
it('should return the response on success', () => {
const expected = { data: ['data'], meta: {} };
const body = JSON.stringify(expected);
const init = { status: 200, statusText: 'OK' };
fetch.mockResponseOnce(body, init);
return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
});
it('should return the statusText for unsuccessful status codes', () => {
const expected = 'Unauthorized';
const body = JSON.stringify({ errors: ['You are not logged in'] });
const init = { status: 401, statusText: expected };
fetch.mockResponseOnce(body, init);
return get('http://endpoint').then(actual => expect(actual).toEqual(expected));
});
// I have not been able to mock this so far
it('handles fetch errors', () => {
return get('doesnotexist').then(actual => expect(actual).toEqual(false));
});
});
});
在最后一个断言中,我想测试它是否捕获了 fetch 抛出的错误(例如,当没有网络连接时)。但我在测试时遇到了麻烦。我不确定我如何模拟提取中的错误然后对其进行测试。有谁知道我将如何模拟最后一个断言?
通过查看 jest-fetch-mock
的实现,它总是解决承诺,这意味着您的 fetch
永远不会去 catch
。所以你需要有一个 Promise.reject()
并且在你的测试中你需要做一些像 -
it('handles fetch errors', () => {
return get('doesnotexist')
.catch(error => expect(error).toEqual('some error'));
});
如果你给它一个无效的主体,它会触发你的 promise 的 catch 部分。
fetch.mockResponseOnce(null, init);