javascript Jest 中的 XHR 测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28584773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:13:25  来源:igfitidea点击:

XHR testing in Jest

javascriptjestjs

提问by Tomasz Kasperek

I want to test AJAX methods (vanilla XHR) and I can't find the way to do it with Jestframework. I found mock-ajax.jsfor Jasmine, the problem is i can't find the way to install it.

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

Is there maybe a better way to Unit Test Ajax functions in Jest?

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

回答by ThaJay

The jest api has changed a bit. This is what I use. It doesn't do anything but it's enough to render my components.

jest api 发生了一些变化。这就是我使用的。它什么都不做,但足以渲染我的组件。

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

window.XMLHttpRequest = jest.fn().mockImplementation(xhrMockClass)

and in the test file:

并在测试文件中:

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

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

回答by Alexander Ivantsov

You can test XHR in Jest without additional packages. This is helper function which creates mock object for XMLHttpRequest:

您可以在 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);
}

And you can use it in test as follows:

您可以在测试中使用它,如下所示:

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
});

回答by M3HD1

As mentioned you don't need additional libraries:

如前所述,您不需要额外的库:

 // mocks.js is where you could put your mocks (example below)
 const mocks = require('./mocks.js')

 test('XHR test', () => {
   let xhrMock = {
      open: jest.fn(),
      setRequestHeader: jest.fn(),
      onreadystatechange: jest.fn(),
      send: jest.fn(),
      readyState: 4,
      responseText: JSON.stringify(mocks),
      status: 200
    }

   window.XMLHttpRequest = jest.fn(() => xhrMock)

   sendData().then((response) => {
      // You could do you checks here. Some examples:
      expect(xhrMock.setRequestHeader).toBeCalledWith('Cache-Control', 'no-cache')
      expect(xhrMock.open).toBeCalledWith('POST', 'you_api_url.com/end_point/')
      expect(xhrMock.withCredentials).toBe(false)

      let formData = new FormData()
      formData.append('firstParam', 'firstParamValue')  

      expect(yoloRequestMock.send).toBeCalledWith(formData)
      expect(JSON.stringify(response)).toBe(JSON.stringify(mocks))
   })
   // when onload is called, resolve and reject has been initialed.
   xhrMock.onreadystatechange()

    // the following function is the one which sends the request (to be tested)
    function sendData() {
       return new Promise(function(resolve, reject) {
         let formData = new FormData()
         formData.append('firstParam', 'firstParamValue')
         let xhr = new XMLHttpRequest()
         xhr.withCredentials = false
         xhr.onreadystatechange = function () {
           if (this.readyState === 4) {
             if(xhr.status === 200) {
               resolve(JSON.parse(xhr.responseText))
             } else {
               reject(xhr.responseText)
             }
           }
         }
         xhr.open('POST', T2S_VISUAL_SEARCH_PARAMS.t2sVisualSeacchApiUrl)
         xhr.setRequestHeader("Cache-Control", "no-cache");
         xhr.send(formData)
       })
    }
  }

The file mocks.jscontains the mocks:

该文件mocks.js包含模拟:

module.exports =
  {
    response: {
      body: { ... }
    }
  }