Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在React组件中测试fetch()方法_Javascript_Reactjs_Jsdom_Enzyme - Fatal编程技术网

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,但是,我仍然看到相同的问题。