【问题标题】:Unit testing react component that makes ajax calls using JEST使用 JEST 进行 ajax 调用的单元测试反应组件
【发布时间】:2015-09-10 13:01:07
【问题描述】:

我有一个在 componentDidMount 方法中进行 AJAX 调用的反应组件。当我尝试使用 React.addons.TestUtils 渲染它时,组件在没有进行 AJAX 调用的情况下被渲染。我将如何使用 jest 测试反应组件以便它进行 AJAX 调用?我是否还需要使用 phantomJS(或类似 env 的浏览器)来提供 DOM 功能来响应组件?

反应组件:

return React.createClass({

  componentDidMount : function() {
    $.ajax({
    ... makes http request
    })
  }

  render : function() {
    <div>
      //view logic based on ajax response...
    </div>
  }
});

测试用例:

jest.dontMock(../MyComponent);

var React = require('react/addons');

var TestUtils = React.addons.TestUtils;

var MyComponent = require(../MyComponent);

describe('Sample Test', function(){     

    it('To Render the component', function() {

       var component = <MyComponent />;

       var DOM = TestUtils.renderIntoDocument(component);

       .... // Some other code... 
       });
})

【问题讨论】:

    标签: ajax unit-testing reactjs jestjs reactjs-testutils


    【解决方案1】:

    其中两个答案涉及模拟服务器,在某些情况下这可能是矫枉过正。我将简要解释一下更简单的方法。

    Jest 将模拟 $.ajax 调用,这意味着 $.ajax.calls[0][0] 将包含拦截的 $.ajax 调用。然后您可以访问调用的成功或错误回调并直接调用它们,例如$.ajax.calls[0][0].success(/* Returned data here. */)

    Jest 的默认设置会自动模拟所有内容,但您明确设置为不模拟的内容除外。因此,假设您使用 successerror 回调调用 $.ajax。 $.ajax.calls 是开玩笑提供的对 $.ajax 函数的调用数组。我们通过索引[0] 获得第一个调用,然后第一个参数与另一个[0] ($.ajax 通常只有一个参数,一个JavaScript 字典/对象)。这使我们能够访问成功和错误回调,允许我们传递我们期望在这些函数上的任意输入并对其进行测试。

    然后您可以正常继续测试您的 ajax 调用的结果。

    【讨论】:

      【解决方案2】:

      如果只需要mock http请求,也可以使用nock。 Sinon 很棒,但附带了许多您可能不需要的附加功能。

      describe('MyComponent', function() {     
        it('successfully makes ajax call and renders correctly', function() {
          // mocks a single post request to example.com/testurl
          var server = nock('http://example.com')
            .post('/testurl')
            .reply(200, 'foo');
      
          var component = <MyComponent />;
          var DOM = TestUtils.renderIntoDocument(component);
        });
      });
      

      请注意,您可能应该在每次测试后调用nock.cleanAll(),这样任何失败或挥之不去的模拟都不会弄乱下一次测试。

      【讨论】:

        【解决方案3】:

        由于您的 $.ajax 被 jest 模拟,因此您没有得到预期的行为,因为您在运行时没有得到真正的 $.ajax 函数。

        您需要模拟您的 $.ajax 函数,以便它更改反应组件的状态。您可以参考此jest 帖子了解详细信息。使用

        $.ajax.mock.calls

        【讨论】:

          【解决方案4】:

          我真的很喜欢Sinon.js 以及它创建一个可以响应用于测试目的的 ajax 请求的假服务器的能力。你可以和 Jest 一起使用它就好了。以下是它可以为您做什么的示例:

          describe('MyComponent', function() {     
          
              it('successfully makes ajax call and renders correctly', function() {
                  //create fake server
                  var server = sinon.fakeServer.create();
                  //make sure that server accepts POST requests to /testurl
                  server.respondWith('POST', '/testurl', 'foo'); //we are supplying 'foo' for the fake response
                  //render component into DOM
                  var component = <MyComponent />;
                  var DOM = TestUtils.renderIntoDocument(component);
                  //allow the server to respond to queued ajax requests
                  server.respond();
                  //expectations go here
                  //restore native XHR constructor
                  server.restore();
              });
          
          });
          

          我不确定您是否愿意在测试套件中包含另一个框架,因此如果它不适合您的目的,请随意忽略此答案。

          【讨论】:

            猜你喜欢
            • 2015-12-06
            • 2017-12-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-20
            • 2020-08-27
            • 2020-05-25
            • 1970-01-01
            相关资源
            最近更新 更多