我有一个使用componentDidMount
方法调用AJAX的react组件。当我尝试使用React.addons.TestUtils
渲染它时,组件在没有进行AJAX调用的情况下被渲染。我如何使用jest测试react组件,以便进行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...
});
})
答案 0 :(得分:12)
我非常喜欢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();
});
});
我不确定你在测试套件中包含另一个框架是多么开放,所以如果它不适合你的目的,请随意忽略这个答案。
答案 1 :(得分:1)
这是一个迟到的答案,但其中两个答案涉及模拟服务器,在某些情况下可能有点过分,实际谈到$.ajax.calls
的答案会导致链接断开,所以我会给出一个对简单方法的简要解释。
jest将模拟$ .ajax调用,这意味着$.ajax.calls[0][0]
将包含截获的$ .ajax调用。然后,您可以访问呼叫的成功或错误回调并直接调用它们,例如$.ajax.calls[0][0].success(/* Returned data here. */)
。
然后你可以正常地测试ajax调用的结果。
答案 2 :(得分:0)
由于你的$ .ajax被jest嘲笑,你没有得到预期的行为,因为你没有在运行时获得真正的$ .ajax函数。
您需要模拟$ .ajax函数,以便更改react组件的状态。有关详细信息,请参阅此jest帖子。使用
$.ajax.mock.calls
&#13;
答案 3 :(得分:0)
如果您只需要模拟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()
,以便任何失败或挥之不去的嘲笑都不会让下一次测试陷入困境。