【问题标题】:React ES6 with chai/sinon: Unit testing XHR in component用 chai/sinon 反应 ES6:在组件中对 XHR 进行单元测试
【发布时间】:2018-01-05 01:35:03
【问题描述】:

我有一个读取 URL 内容的 React 实用程序组件:

'use strict';

export class ReadURL {

  getContent = (url) => {
      return new Promise((resolve, reject) => {
console.log('Promise')
          let xhr = new XMLHttpRequest();

          xhr.open("GET", url, false);
          xhr.onreadystatechange = () => {
console.log('onreadystatechange', xhr.readyState)
              if (xhr.readyState === 4) {
                  if (xhr.status === 200 || xhr.status == 0) {
console.log('200')
                      var allText = xhr.responseText;
                      resolve(allText);
                  } else {
                      reject('ajax error:' + xhr.status + ' ' + xhr.responseText);
                  }
              }
          };
          xhr.send(null);
      });
  };

}

我一直在尝试使用 Sinon 的 useFakeXMLHttpRequest() 来存根 xhr,但无论我如何尝试,我都无法让它实际处理 - 它目前以误报通过,没有收到 onreadystatechange 事件. 我已经尝试过使用 XHR 和 Axios 包以及原生 XMLHttpRequest,请求包含在一个承诺中,而不是,一大堆不同的策略,并阅读了无数的博客文章、文档和 SO 问题,我正在失去对live...组件本身完美运行。

我已经设法让测试与 Promise 和存根模块依赖项一起工作,但这让我很难过。

这是测试:

import chai, { expect } from 'chai';
import sinon, { spy } from 'sinon';

import {ReadURL} from './ReadURL';


describe('ReadURL', () => {

  beforeEach(function() {

    this.xhr = sinon.useFakeXMLHttpRequest();

    this.requests = [];
    this.xhr.onCreate = (xhr) => {
console.log('xhr created', xhr)
      this.requests.push(xhr);
    };

    this.response = 'Response not set';
  });

  afterEach(function() {
    this.xhr.restore();

    this.response = 'Response not set';
  });

  it('should get file content from an xhr request', () => {
    const readURL = new ReadURL(),
          url = 'http://dummy.com/file.js',
          urlContent = `<awe.DisplayCode
            htmlSelector={'.awe-login'}
            jsxFile={'/src/js/components/AncoaAwe.js'}
            jsxTag={'awe.Login'}
            componentFile={'/src/js/components/Login/Login.js'}
          />`;

    readURL.getContent(url).then((response) =>{
console.log('ReadURL-test response', response)
            expect(response).to.equal(urlContent);
          });


    window.setTimeout(() => {
console.log('ReadURL-test trigger response')
      this.requests[0].respond(200,
        {
          'Content-Type': 'application/json'
        },
        urlContent
      )
    , 10});

  });

});

console.log('xhr created', xhr) 被触发,输出确认这是一个 sinon useFakeXMLHttpRequest 请求。

我已经创建了一个应用程序存储库,其中包含查看组件功能所需的最低要求: https://github.com/DisasterMan78/awe-testcase

我目前没有在线示例,因为我不知道有任何在线沙盒运行测试。如果我能找到一项服务,我会尝试添加一个失败概念的证明。

帮助我欧比万-克诺比。你是我唯一的希望!

【问题讨论】:

    标签: reactjs unit-testing xmlhttprequest sinon chai


    【解决方案1】:

    嗯,那很有趣。在完成一个较旧的项目后,我今天回到了它,但它仍然花了我太长时间。愚蠢的,小的语法错误。当然……

    有两个严重错误。

    首先,为了完成promise,需要将done作为参数传递给测试的it()函数的函数:

    it('should get file content from an xhr request', (done) => {
      ...
    }
    

    现在我们可以用 done 完成承诺:

        ...
        readURL.getContent(url)
          .then((response) => {
            expect(response).to.equal(this.response.content);
            done();
          })
          .catch((error) => {
    console.log(error);
            done();
          });
        ...
    

    不知何故,我阅读的文档或文章似乎都没有标记这一点,但其中很少有人也处理承诺,而我的 ExtractTagFromURL 测试也依赖于承诺,但我已经确认它是对这个测试绝对至关重要。

    在 Promise 正常工作的情况下,respond() 调用不需要超时:

        ...
        this.requests[0].respond(this.response.status,
          {
            'Content-Type': this.response.contentType
          },
          this.response.content
        );
        ...
    

    最后,我最大的胆子,为了正确设置和读取this.requeststhis 和其他共享属性的值,beforeEach()afterEach() 的函数参数需要使用箭头语法:

      ...
      beforeEach(() => {
        ...
      }
      ...
    

    Github 上的精简测试用例已更新,通过并可从https://github.com/DisasterMan78/awe-testcase 克隆

    我想这让我成为了欧比万-基诺贝,是吧?

    如有需要,请随时要求澄清!

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 2017-06-09
      • 2019-02-14
      • 2016-05-26
      • 2021-09-27
      • 2023-04-11
      • 1970-01-01
      • 2015-05-16
      相关资源
      最近更新 更多