在Jest中进行XHR测试

Tom*_*rek 16 javascript jestjs

我想测试AJAX方法(vanilla XHR),我找不到使用Jest框架的方法.我找到mock-ajax.js了Jasmine,问题是我找不到安装它的方法.

是否有更好的方法在Jest中单元测试Ajax函数?

Tha*_*Jay 19

开玩笑api已经改变了一点.这就是我使用的.它没有做任何事情,但它足以渲染我的组件.

const xhrMockClass = () => ({
  open            : jest.fn(),
  send            : jest.fn(),
  setRequestHeader: jest.fn()
})

window.XMLHttpRequest = jest.fn().mockImplementation(xhrMockClass)
Run Code Online (Sandbox Code Playgroud)

并在测试文件中:

import '../../__mock__/xhr-mock.js'


sim*_*n04 16

以下是使用 Jest 26 的 TypeScript 示例:

function performRequest(callback: any) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.com/');
  xhr.onreadystatechange = () => {
    if (xhr.readyState !== 4 || xhr.status !== 200) return;
    callback(xhr.response);
  };
  xhr.responseType = 'json';
  xhr.setRequestHeader('Accept', 'application/json');
  xhr.send(null);
}

describe('request', () => {
  const xhrMock: Partial<XMLHttpRequest> = {
    open: jest.fn(),
    send: jest.fn(),
    setRequestHeader: jest.fn(),
    readyState: 4,
    status: 200,
    response: 'Hello World!'
  };

  jest.spyOn(window, 'XMLHttpRequest').mockImplementation(() => xhrMock as XMLHttpRequest);
  const callback = jest.fn();
  performRequest(callback);
  expect(xhrMock.open).toBeCalledWith('GET', 'https://example.com/');
  expect(xhrMock.setRequestHeader).toBeCalledWith('Accept', 'application/json');
  (xhrMock.onreadystatechange as EventListener)(new Event(''));
  expect(callback.mock.calls).toEqual([['Hello World!']]);
});
Run Code Online (Sandbox Code Playgroud)


小智 15

您可以在没有其他包的情况下在Jest中测试XHR.这是辅助函数,它为XMLHttpRequest创建模拟对象:

let open, send, onload, onerror;

function createXHRmock() {
    open = jest.genMockFn();

    // be aware we use *function* because we need to get *this* 
    // from *new XmlHttpRequest()* call
    send = jest.genMockFn().mockImpl(function(){   
        onload = this.onload.bind(this);
        onerror = this.onerror.bind(this);
    });

    const xhrMockClass = function () {
        return {
            open,
            send
        };
    };

    window.XMLHttpRequest = jest.genMockFn().mockImpl(xhrMockClass);
}
Run Code Online (Sandbox Code Playgroud)

你可以在测试中使用它如下:

it('XHR success', () => {
    createXHRmock();

    // here you should call GET request

    expect(open).toBeCalledWith('GET', 'http://example.com', true);
    expect(send).toBeCalled();

    // call onload or onerror
    onload();

    // here you can make your assertions after onload
});
Run Code Online (Sandbox Code Playgroud)

  • 我认为现在这是来自[docs](https://facebook.github.io/jest/docs/en/mock-function-api.html#mockfnmockimplementationfn)的`jest.fn().mockImplementation` (2认同)