使用 jest/enzyme 测试调用 setState 的异步 componentDidMount

nri*_*ion 1 reactjs jestjs enzyme

我的里面有以下代码async componentdidmount

async componentDidMount() {
    try {
        let responseText = await API.Licensing()
        this.setState({ html: responseText })
    } catch (e) {
        this.setState({ html: 'Error Fetching Licensing Info' })
    }
}
Run Code Online (Sandbox Code Playgroud)

我对如何在这里测试 setstate 感到困惑,因为互联网上的大多数示例都使用 Promise then/catch,而这个示例使用 try/catch async/await。

测试会是什么样子?

geo*_*doo 5

import React from "react";
import {
    shallow
} from "enzyme";
import axios from "axios";
import App from "./App";

jest.mock("axios");

it("fetches html", done => {
    const responseText = 'some text';
    axios.get.mockResolvedValueOnce(responseText);
    const wrapper = shallow( < App / > );

    setImmediate(() => {
        expect(wrapper.state().html).toBe('some text');
        done();
    });
});

it("transmits a useful message when fetching is not successful", done => {
    axios.get.mockImplementation(() => Promise.reject(new Error('error')))

    const wrapper = shallow( < App / > );

    setImmediate(() => {
        expect(wrapper.state().html).toBe("error");
        done();
    });
});
Run Code Online (Sandbox Code Playgroud)

我想你可以用上面的API替换axios。你需要自己尝试一下。就像是:

import API from './API';

jest.mock("API");

... API.Licensing.mockResolvedValueOnce(responseText);
Run Code Online (Sandbox Code Playgroud)

另一件事是,您可能不需要那里的did参数,因为 api 响应已被存根,但安全总比抱歉好!也需要检查这个:)(我必须设置一个项目来检查这个,因为我很好奇......)

PS:对于多个 Promise,您只需要根据您的需要存根 api 响应,更改mockResolvedValueOnce即可。检查这里: https: //jestjs.io/docs/en/mock-function-api.html

说明:您模拟了 API 响应并浅化了组件。然后您需要在 setImmediate 函数内执行所有检查。老实说,这个函数放在哪里并不重要。如果您好奇,请尝试将其放在测试块的顶部。它总是在所有承诺和回调都解决后最后执行。或者,您可以使用 process.nextTick 或 setTimeout 以及 0 时间参数。您可以在此处的 NodeJS 文档中找到更多信息:https ://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

基本上,您可以利用 JS 事件循环、计时器回调等的不同队列