我的组件上有一个异步componentDidMount
函数,该函数进行API调用并更新mobx
存储。该组件具有@observer
批注。
我已经模拟了API,但是遇到了麻烦-我无法弄清楚如何在测试中等待该生命周期方法:
it("Magick", async () => {
const comp = await mount(<Comp/>); // -- no point of await here
// await comp.instance().componentDidMount(); -- should work, even if function is called wtice
// await new Promise((resolve) => setTimeout(resolve, 100)); // -- smelly and prone to crashing
expect(Axios.post).toBeCalledTimes(1);
expect(MobX.value).toBe(-1);
comp.unmount();
});
组件片段:
componentDidMount = async () => {
try {
const result = await AxiosWrapper.GetValue();
if (result) {
const errors = Parser.getErrors(result);
if (errors) {
console.log(errors);
} else {
MobX.value = Parser.getValue(result)
}
}
} catch (e) {
console.log(e);
}
};
Axios包装器方法:
static async GetValue() {
return await Axios.post(...);
}
我发现的唯一解决方案是添加超时,但这是不可接受的。我找到的任何其他解决方案都行不通-有什么想法吗?
答案 0 :(得分:2)
为了使组件可测试,应该有一个链接的承诺。该组件的问题在于componentDidMount
是实例方法,无法在实例化该组件之前对其进行监视或模拟。相反,它应该是:
async componentDidMount() {
...
}
然后可以在类原型上进行监视:
const cdmSpy = jest.spyOn(Comp.prototype, 'componentDidMount');
const comp = mount(<Comp/>);
await cdmSpy.mock.results[0].value;
...
或者,可以手动调用componentDidMount
并与酶disableLifecycleMethods
选项一起进行测试。
答案 1 :(得分:0)
感谢@estus指向我正确的方向。
我通过以下方式解决了该问题:
componentDidMount
调用一个单独的函数other
。other
,await spy.mock.results[0].value;
如果我尝试直接监视componentDidMount
,则会收到错误消息:TypeError: object[methodName].mockImplementation is not a function
。
这可能是因为所讨论的组件上有@observer
和@withNamespaces
装饰符。