原文鏈接:https://github.com/ctimmerm/axios-mock-adapter
Axios適配器,允許輕鬆模擬請求
安裝
使用npm:
$ npm install axios-mock-adapter --save-dev
它也可用作UMD版本:
- https://unpkg.com/axios-mock-adapter/dist/axios-mock-adapter.js
- https://unpkg.com/axios-mock-adapter/dist/axios-mock-adapter.min.js
axios-mock-adapter適用於Node和瀏覽器,適用於axios v0.9.0及更高版本。
案例
模擬GET
請求
var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');
// 這將模擬適配器設置爲默認實例
var mock = new MockAdapter(axios);
// 將任何GET請求模擬到 /users
// 用於回覆的參數是(status,data,headers)
mock.onGet('/users').reply(200, {
users: [
{ id: 1, name: 'John Smith' }
]
});
axios.get('/users')
.then(function(response) {
console.log(response.data);
});
模擬GET
使用特定參數請求
var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');
// 這將模擬適配器設置爲默認實例
var mock = new MockAdapter(axios);
// 當param`searchText`爲'John'時,向 /users使用Mock GET請求
// 回覆的參數是(status,data,headers)
mock.onGet('/users', { params: { searchText: 'John' } }).reply(200, {
users: [
{ id: 1, name: 'John Smith' }
]
});
axios.get('/users', { params: { searchText: 'John' } } )
.then(function(response) {
console.log(response.data);
});
要爲響應添加延遲,請在實例化適配器時指定延遲量(以毫秒爲單位)
//使用此實例的所有請求都將延遲2秒:
var mock = new MockAdapter(axiosInstance, { delayResponse: 2000 });
您可以恢復原始適配器(這將刪除模擬行爲)
mock.restore();
您還可以使用重置已註冊的模擬處理程序 resetHandlers
mock.resetHandlers();
您可以使用重置已註冊的模擬處理程序和歷史記錄項 reset
mock.reset();
reset
不同於restore的地方
在於restore
完全去除的axios實例的mocking,而reset
只有消除了所增加與使用onGET,onPOST等,等所有的模擬處理,但留下mocking到位。
模擬低級網絡錯誤
// 返回帶有錯誤的失敗promise ('Network Error');
mock.onGet('/users').networkError();
//networkErrorOnce可以用來模擬網絡錯誤只有一次
mock.onGet('/users').networkErrorOnce();
模擬網絡超時
// 返回與設置爲“ECONNABORTED”代碼錯誤失敗的promise
mock.onGet('/users').timeout();
// timeoutOnce只能用於模擬一次模擬超時
mock.onGet('/users').timeoutOnce();
將功能傳遞給 reply
mock.onGet('/users').reply(function(config) {
//`config`是axios配置,包含url之類的東西
// 以[status,data,headers]的形式返回數組
return [200, {
users: [
{ id: 1, name: 'John Smith' }
]
}];
});
將函數傳遞給reply
它會返回一個axios請求,主要是模擬重定向
mock.onPost('/foo').reply(function(config) {
return axios.get('/bar');
});
使用正則表達式
mock.onGet(/\/users\/\d+/).reply(function(config) {
// 可以從config.url中獲取實際id
return [200, {}];
});
在正則表達式中使用變量
const usersUri = '/users';
const url = new RegExp(`${usersUri}/*`);
mock.onGet(url).reply(200, users);
僅通過動詞指定不匹配的路徑
// Reject all POST requests with HTTP 500
mock.onPost().reply(500);
鏈接也受支持
mock
.onGet('/users').reply(200, users)
.onGet('/posts').reply(200, posts);
.replyOnce()
可以用來讓mock只回復一次
mock
.onGet('/users').replyOnce(200, users) // 第一次請求 /users後,這個此處理程序會被刪除
.onGet('/users').replyOnce(500); // 對/users的第二個請求將具有狀態代碼500
// 任何後續請求都將返回404,因爲沒有匹配的處理程序
將任何請求模擬到給定的URL
// 模擬GET,POST,...請求/foo
mock.onAny('/foo').reply(200);
.onAny
當您想要測試特定的請求順序時,它會很有用
// 預期的請求順序:
const responses = [
['GET', '/foo', 200, { foo: 'bar' }],
['POST', '/bar', 200],
['PUT', '/baz', 200]
];
// //匹配所有模擬請求
mock.onAny().reply(config => {
const [method, url, ...response] = responses.shift();
if (config.url === url && config.method.toUpperCase() === method) return response;
//意想不到的請求,錯誤輸出
return [500, {}];
});
使用HTTP 404響應拒絕不映射到模擬處理程序的請求。由於處理程序按順序匹配,onAny()
因此可以使用final 來更改默認行爲
// Mock GET請求 /foo,拒絕所有其他人使用HTTP 500
mock
.onGet('/foo').reply(200)
.onAny().reply(500);
使用特定請求正文/數據模擬請求
mock.onPut('/product', { id: 4, name: 'foo' }).reply(204);
.passThrough()
通過網絡轉發匹配的請求
// Mock POST requests to /api with HTTP 201, but forward
// GET requests to server
mock
.onPost(/\/^api/).reply(201)
.onGet(/\/^api/).passThrough();
回想一下處理程序的順序很重要
// Mock specific requests, but let unmatched ones through
mock
.onGet('/foo').reply(200)
.onPut('/bar', { xyz: 'abc' }).reply(204)
.onAny().passThrough();
請注意,passThrough
請求不會延遲delayResponse
。
從1.7.0開始,reply
函數可能會返回一個Promise:
mock.onGet('/product').reply(function(config) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
if (Math.random() > 0.1) {
resolve([200, { id: 4, name: 'foo' } ]);
} else {
// reject() reason will be passed as-is.
// Use HTTP error status code to simulate server failure.
resolve([500, { success: false } ]);
}
}, 1000);
});
});
使用Promises從多個來源編寫:
var normalAxios = axios.create();
var mockAxios = axios.create();
var mock = new MockAdapter(mockAxios);
mock
.onGet('/orders')
.reply(() => Promise.all([
normalAxios
.get('/api/v1/orders')
.then(resp => resp.data),
normalAxios
.get('/api/v2/orders')
.then(resp => resp.data),
{ id: '-1', content: 'extra row 1' },
{ id: '-2', content: 'extra row 2' }
]).then(
sources => [200, sources.reduce((agg, source) => agg.concat(source))]
)
);
歷史
該history
屬性允許您枚舉現有的axios請求對象。該屬性是動詞鍵的對象,引用請求對象的數組。
這對測試很有用。
describe('Feature', () => {
it('requests an endpoint', (done) => {
var mock = new AxiosMockAdapter(axios);
mock.onPost('/endpoint').replyOnce(200);
feature.request()
.then(() => {
expect(mock.history.post.length).toBe(1);
expect(mock.history.post[0].data).toBe(JSON.stringify({ foo: 'bar' }));
})
.then(done)
.catch(done.fail);
});
});
您可以清除歷史記錄 resetHistory
mock.resetHistory();