2016-04-20 65 views
1

我有一個應用程序組件負責渲染子輸入組件,它也負責通過名爲channelSearch的方法處理對Twitch API的提取請求。我試圖遵循建議的最佳實踐here與React一起使用ajax/fetch。測試React組件中的fetch()方法

該方法通過道具傳遞並通過回調調用。

注意fetch方法實際上是同構獲取。

channelSearch (searchReq, baseUrl="https://api.twitch.tv/kraken/channels/") { 
    fetch(baseUrl + searchReq) 
    .then(response => { 
    return response.json(); 
    }) 
    .then(json => { 
    this.setState({newChannel:json}); 
    }) 
    .then(() => { 
    if (!("error" in this.state.newChannel) && this.channelChecker(this.state.newChannel._id, this.state.channelList)) { 
     this.setState(
     {channelList: this.state.channelList.concat([this.state.newChannel])} 
    ); 
    } 
    }) 
    .catch(error => { 
    return error; 
    }); 
} 

我目前正在嘗試編寫一個channelSearch方法的測試。我目前在DOM中使用酶和jsdom整個<App>組件。用回調查找子節點,模擬點擊(應該觸發回調)並檢查組件的狀態是否已更改。但是,這似乎並不奏效。

我也嘗試過直接調用方法,但是,我遇到了this.state未定義的問題。

test('channel search method should change newChannel state', t => { 
    const wrapper = mount(React.createElement(App)); 

    wrapper.find('input').get(0).value = "test"; 
    console.log(wrapper.find('input').get(0).value); 
    wrapper.find('input').simulate("change"); 

    wrapper.find('button').simulate("click"); 

    console.log(wrapper.state(["newChannel"])); 


}); 

我真的失去了,我不知道,如果該方法本身寫得不好或者我沒有使用正確的工具作業。任何指導將不勝感激。

更新#1:

我包括箭扣在意見建議,測試現在看起來是這樣的:

test('channel search method should change newChannel state', t => { 
    // Test object setup 

    var twitch = nock('https://api.twitch.tv') 
       .log(console.log) 
       .get('/kraken/channels/test') 
       .reply(200, { 
        _id: '001', 
        name: 'test', 
        game: 'testGame' 
       }); 

    function checker() { 
    if(twitch.isDone()) { 
     console.log("Done!"); 
     console.log(wrapper.state(["newChannel"])); 
    } 
    else { 
     checker(); 
    } 
    } 

    const wrapper = mount(React.createElement(App)); 
    wrapper.find('input').get(0).value = "test"; 
    wrapper.find('input').simulate("change"); 
    wrapper.find('button').simulate("click"); 

    checker(); 
}); 

這似乎仍然沒有改變組件的狀態。

+0

請包括您的測試,因爲它們顯然是問題的一部分:) – markthethomas

+0

@markthethomas新增,感謝您的興趣! –

回答

1

提取是異步的,但您正在同步測試,您需要使用同步模擬模擬提取或使測試異步。

nock可能適合你。

+0

我已經更新了我的測試,試圖嘗試用nock模擬提取,但是,我仍然看到相同的問題。 –

0

我建議你使用plnkr創建一個你的測試樣本。

我同意湯姆,你正在同步測試。當然,這將是有益的炫耀您的實際組件代碼(所有相關的部分,比如什麼叫channelSearch,或者至少說,例如「channelSearchcomponentDidMount()稱爲」形容你說:

我遇到的問題與this.state被不確定的。

這是因爲this.setState() is asynchronous,這是出於性能的考慮,讓陣營可以批量修改。

我懷疑你需要改變你的代碼,目前:

.then(json => { 
    this.setState({newChannel:json}); 
}) 

到:

.then(json => { 
    return new Promise(function(resolve, reject) { 
    this.setState({newChannel:json}, resolve); 
    }) 
}) 

請注意,您checker()方法是行不通的。它正在循環,但twitch.isDone()永遠不會是真的,因爲它從來沒有機會運行。 Javascript是單線程的,所以你的檢查代碼會連續運行,不允許其他任何東西。

如果你設置了plnkr,我會看看。

相關問題