2015-06-24 69 views
7

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

阵营组件:

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

回答

10

我真的很喜欢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(); 
    }); 

}); 

我不知道你要包括在您的测试套件另一个框架可以随意忽略这个答案,如果它不适合你的目的是如何打开。

0

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

您需要模拟您的$ .ajax函数,以便它改变反应组件的状态。详情请参阅jest的帖子。使用

$.ajax.mock.calls

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()每次测试后,使任何故障或缠绵嘲笑不要弄乱下一个测试。

0

这是一个迟到的答案,但其中两个答案涉及嘲笑服务器,在某些情况下可能会矫枉过正,而实际上谈到$.ajax.calls的答案会导致链接断开,所以我将简要解释更简单的方法来做到这一点。

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

然后,您可以正常进行测试ajax调用的结果。

+0

你能否扩展你的答案以更好地描述jest会如何嘲笑$ .ajax? –

+0

为jest设置的默认设置自动模拟除了您专门设置为不模拟的事物之外的所有内容。假设你使用'success'和'error'回调调用$ .ajax。 $ .ajax.calls是提供给$ .ajax函数调用的数组的调用。我们通过索引[0]得到第一个调用,然后第一个参数与另一个[0]($ ​​.ajax通常只有一个参数,一个javascript字典/对象)。这使我们可以访问成功和错误回调,从而允许我们传递我们对这些函数的任意输入并对它们进行测试。希望这是有道理的? –