axios-mock-adapter插件

原文链接:https://github.com/ctimmerm/axios-mock-adapter

原文链接:https://github.com/ctimmerm/axios-mock-adapter

 

Axios适配器,允许轻松模拟请求

安装

使用npm:

$ npm install axios-mock-adapter --save-dev

它也可用作UMD版本:

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();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章