Javascript 在React组件中测试fetch()方法
我有一个应用程序组件,负责呈现子输入组件,它还负责通过名为Javascript 在React组件中测试fetch()方法,javascript,reactjs,jsdom,enzyme,Javascript,Reactjs,Jsdom,Enzyme,我有一个应用程序组件,负责呈现子输入组件,它还负责通过名为channelSearch的方法处理对Twitch API的获取请求。我已经试着坚持推荐的使用React的ajax/fetch的最佳实践 该方法通过props传递,并通过回调调用 注意fetch方法实际上是同构的fetch channelSearch (searchReq, baseUrl="https://api.twitch.tv/kraken/channels/") { fetch(baseUrl + searchReq)
channelSearch
的方法处理对Twitch API的获取请求。我已经试着坚持推荐的使用React的ajax/fetch的最佳实践
该方法通过props传递,并通过回调调用
注意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
方法编写一个测试。我目前正在使用Ezyme和jsdom在DOM中装载整个
组件。找到具有回调的子节点,模拟单击(这将触发回调)并检查组件的状态是否已更改。然而,这似乎不起作用
我也尝试过直接调用该方法,但是,我遇到了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:
.then(json => {
this.setState({newChannel:json});
})
.then(json => {
return new Promise(function(resolve, reject) {
this.setState({newChannel:json}, resolve);
})
})
我在评论中推荐了nock,现在的测试如下:
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();
});
这似乎仍然不会改变组件的状态。获取是异步的,但如果要同步测试,则需要使用同步模拟进行模拟获取,或者使测试异步
可能在这里对您有用。我建议您使用创建一个测试样本 我同意汤姆的观点,你是同步测试的。当然,展示您的实际组件代码会很有帮助(所有相关部分,比如称为
channelSearch
,或者至少通过这样的方式来描述它:“channelSearch
由componentDidMount()调用
”。您说:
我遇到了此.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"]));
});
这是因为。这是出于性能原因,所以React可以批量更改
我怀疑您需要更改当前的代码:
.then(json => {
this.setState({newChannel:json});
})
.then(json => {
return new Promise(function(resolve, reject) {
this.setState({newChannel:json}, resolve);
})
})
至:
.then(json => {
this.setState({newChannel:json});
})
.then(json => {
return new Promise(function(resolve, reject) {
this.setState({newChannel:json}, resolve);
})
})
请注意,您的checker()
方法将不起作用。它是循环的,但twitch.isDone()
将永远不会为真,因为它永远不会有机会运行。Javascript是单线程的,因此您的checker代码将连续运行,不允许在这两者之间执行任何其他操作
如果您设置了plnkr,我会看一看。从组件中重构
获取
代码,然后将其作为属性中的回调函数传递给组件
导出类通道扩展React.Component{
componentDidMount(){
this.props.searchFunction().then(data=>this.setState(data));
}
render(){
返回{this.state};
}
}
语言:
函数通道搜索(名称){
回传(`https://api.twitch.tv/kraken/search/channels?query=${name}`);
}
现在,您可以独立于组件测试API功能。请包括您的测试,因为它们显然是问题的一部分:)@markthethomas已添加,感谢您的关注!我已经更新了我的测试,尝试按照建议使用nock模拟fetch,但是,我仍然看到相同的问题。