要测试的组件
class Carousel extends React.Component { state = { slides: null } componentDidMount = () => { axios.get("https://s3.amazonaws.com/rainfo/slider/data.json").then(res => { this.setState({ slides: res.data }) }) } render() { if (!slides) { return null } return ( <div className="slick-carousel"> ... markup trancated for bravity </div> ) } } export default Carousel
测试
import React from "react" import renderer from "react-test-renderer" import axios from "axios" import Carousel from "./Carousel" const slides = [ { ID: "114", REFERENCE_DATE: "2018-07-02", ... }, { ID: "112", REFERENCE_DATE: "2018-07-06", ... }, ... ] jest.mock("axios") it("", () => { axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides })) const tree = renderer.create(<Carousel />).toJSON() expect(tree).toMatchSnapshot() })
快照只记录null,因为我想在执行的那一刻state.slides = null。
null
state.slides = null
在axios完成获取数据后,我不能指望如何运行期望值。
在线上的大多数样本要么使用酶,要么显示具有返回承诺的异步功能的测试。我找不到一个仅使用笑话和渲染组件显示示例的示例。
我尝试使测试功能async,也使用done回调,但没有运气。
async
done
简而言之:
it("", async () => { axios.get.mockImplementationOnce(() => Promise.resolve({ data: slides })) const tree = renderer.create(<Carousel />); await Promise.resolve(); expect(tree.toJSON()).toMatchSnapshot() })
应该做的工作
详细信息:除了您模拟的对API数据的调用之外,异步调用仍在进行。因此,我们需要将toMatchSnapshot调用转到微任务队列的末尾。setTimeout(..., 0)或setImmediate也可以使用,但是我发现await Promise.resolve()它更好地被识别为“下面的所有内容都将排在队列末尾”
toMatchSnapshot
setTimeout(..., 0)
setImmediate
await Promise.resolve()
[UPD]固定代码段:.toJSON必须在等待之后,它返回的对象将永远不会更新
.toJSON