2015-06-24 96 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字典/對象)。這使我們可以訪問成功和錯誤回調,從而允許我們傳遞我們對這些函數的任意輸入並對它們進行測試。希望這是有道理的? –