我的react组件使用lodash debounce运行异步查询以获取一些数据-因为用户输入可能会导致重新查询,并且我想对查询进行速率限制-然后使用结果设置组件的状态返回。
我的组件(反应组件)
componentWillMount() {
this.runQuery();
}
handler = (response) => {
this.setState({ results: response.results });
}
runQuery = _.debounce((props = this.props) => {
// run the query
doStuff(mainParams)
.withSomeOtherStuff(moreParams)
.query()
.then(this.handler)
.catch((error) => {
this.props.catchError(error);
});
}, 200);
由于sinon-stub-promise
软件包,我目前正在对主要的api出口点进行存根并获取返回承诺的数据
before((done) => {
stub = stubGlobalFn('evaluate'); // returns stubbed promise, uses npm:sinon-stub-promise
});
这使我能够使用自定义的Reader(在其他地方测试)读取模拟响应,然后出于测试目的同步解析它。
mytest.spec.jsx
let stub;
const testWithProps = props => (
new Promise((resolve, reject) => {
new Reader(histories).readGrid((err, grid) => {
try {
expect(err).to.be.a('null');
stub.resolves(grid);
// ....
然后,在相同的testWithProps
函数中,我可以将Table
组件与我在测试中指定的道具一起挂载,作为某种测试工厂。
const wrapper = mount(<Table {...props} />);
在这里,我陷入了困惑,我放弃了当调用主要evaluate
异步函数而不是状态处理程序时可以解决的诺言。
stub.thenable.then(() => {
// --------------------------
// PROBLEM: how to test without setting a timeout?
// --------------------------
setTimeout(() => {
resolve(wrapper.update());
}, 200);
// --------------------------
// --------------------------
});
如果要在异步行为之后测试组件 的状态,我应该在我的react组件中插入handler
函数吗?我不确定如果需要的话,该如何将其分开。
最终我的测试看起来像这样:
it('toggles the row for the value when clicked', () => {
const props = {
// some props that I use
};
return testWithProps(props).then((wrapper) => {
// simply testing that my mocked response made it in successfully to the rendered component
expect(wrapper.state().results.length).to.equal(4);
});
});