反应,酶异步生命周期功能

时间:2019-01-04 12:54:56

标签: reactjs jestjs enzyme mobx

我的组件上有一个异步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(...);
}

我发现的唯一解决方案是添加超时,但这是不可接受的。我找到的任何其他解决方案都行不通-有什么想法吗?

2 个答案:

答案 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
  • spyOn otherawait spy.mock.results[0].value;

如果我尝试直接监视componentDidMount,则会收到错误消息:TypeError: object[methodName].mockImplementation is not a function

这可能是因为所讨论的组件上有@observer@withNamespaces装饰符。

相关问题