2016-04-20 61 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,我会看看。

相关问题