Vic*_*ong 11 unit-testing asynchronous reactjs jestjs enzyme
在我的create-react-app中,我试图测试一个setState在安装时执行多个s 的组件.
class MyComponent extends React.Component {
state = {
a: undefined,
b: undefined,
c: undefined,
};
fetchA() {
// returns a promise
}
fetchB() {
// returns a promise
}
fetchC() {
// returns a promise
}
async componentDidMount() {
const a = await fetchA();
this.setState({ a });
}
async componentDidUpdate(prevProps, prevState) {
if (prevState.a !== this.state.a) {
const [b, c] = await Promise.all([
this.fetchB(a);
this.fetchC(a);
]);
this.setState({ b, c });
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我做了类似这样的事情,在做出断言之前尝试让setStatein componentDidUpdate完成.
import { mount } from 'enzyme';
describe('MyComponent', () => {
const fakeA = Promise.resolve('a');
const fakeB = Promise.resolve('b');
const fakeC = Promise.resolve('c');
MyComponent.prototype.fetchA = jest.fn(() => fakeA);
MyComponent.prototype.fetchB = jest.fn(() => fakeB);
MyComponent.prototype.fetchC = jest.fn(() => fakeC);
it('sets needed state', async () => {
const wrapper = mount(<MyComponent />);
await Promise.all([ fakeA, fakeB, fakeC ]);
expect(wrapper.state()).toEqual({
a: 'a',
b: 'b',
c: 'c',
});
});
});
Run Code Online (Sandbox Code Playgroud)
这是有趣的部分:上面的测试将失败,因为在进行断言时,最后一次setState调用(in componentDidUpdate)还没有完成.当时,state.a被设置的,但state.b并state.c没有被设定.
我能使其工作的唯一方法是await Promise.resolve(null)在断言之前楔入,以便最后setState完成额外的滴答/循环.这看起来太hacky了.
我尝试过的另一件事是将断言包装进去setImmediate(),只要断言通过就可以正常工作.如果失败,它将因未捕获的错误而终止整个测试.
有没有人克服这个问题?
我就是这样解决的。希望能帮助某人。
import { mount } from 'enzyme';
describe('MyComponent', () => {
const fakeA = Promise.resolve('a');
const fakeB = Promise.resolve('b');
const fakeC = Promise.resolve('c');
MyComponent.prototype.fetchA = jest.fn(() => fakeA);
MyComponent.prototype.fetchB = jest.fn(() => fakeB);
MyComponent.prototype.fetchC = jest.fn(() => fakeC);
it('sets needed state', async (done) => {
const wrapper = mount(<MyComponent />);
await Promise.all([ fakeA, fakeB, fakeC ]);
setImmediate(() => {
// Without the try catch, failed expect will cause the
// whole test to crash out.
try {
expect(wrapper.state()).toEqual({
a: 'a',
b: 'b',
c: 'c',
});
} catch(error) {
done.fail(error);
}
done();
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4195 次 |
| 最近记录: |