11

我有一个在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... 
       });
})
4

4 回答 4

13

我真的很喜欢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-06-24T14:09:04.517 回答
2

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

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

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

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

于 2016-10-31T15:47:05.480 回答
1

如果只需要 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()在每次测试后调用,这样任何失败或挥之不去的模拟都不会弄乱下一次测试。

于 2016-10-20T16:20:52.557 回答
0

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

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

$.ajax.mock.calls

于 2015-06-27T02:20:18.467 回答