reactjs - 开玩笑地在不同的模拟 API 调用中返回不同的数据
问题描述
我开始学习更多关于使用 Jest 和 testing-library 测试 React 组件的知识。我使用模拟 API 返回用户数据并在我的测试中呈现它,并希望user_active = true
在第一个 API 调用和user_active = false
第二个 API 调用中返回。
这是我在mocks文件夹中模拟 getUsers API 的代码:
"use strict";
module.exports = {
getUsers: () => {
return Promise.resolve({
data: {
id: 27,
full_name: "john doe",
username: "jhon",
is_active: true,
},
});
},
}
这是我的组件,用户信息是一个包含(id、full_name、username、is_active)的对象:
class Users extends Component {
constructor(props) {
super(props);
this.state = {
userInfo: null,
};
}
getUsers = () => {
const token = this.props.token;
myAPI.getUsers(token)
.then((res) => {
this.setState({
data: res.data,
error: null,
});
})
.catch((error) => {
this.setState({
error: error,
data: [],
});
});
};
refreshList = () => {
this.getUsers();
};
render() {
return (
<div>
<a data-testid="refresh-button" onClick = {this.refreshList}>load user data </a>
<span> {this.state.userInfo.username}</span>
<span> {this.state.userInfo.is_active}</span>
</div>
)
}
}
这是我的测试:
import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
jest.mock("../MyApi");
import Users from "./index";
test("load users twice", async () => {
let baseDom = render(<Users/>);//first API call
expect(await baseDom.findByText("true")).toBeInTheDocument();
fireEvent.click(await baseDom.findByTestId("refresh-button")); //to second api call
expect(await baseDom.findByText("false")).toBeInTheDocument();
});
如何在第一次/第二次 API 调用中返回不同的数据?
解决方案
您可以通过使用方法来实现这一点jest.mockResolvedValueOnce()
,请查看文档以获取有关该方法如何工作的更多信息。
import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Users from "./index";
import myApi from '../MyApi'
it('should give two different results', () => {
const firstMockReturn = {
id: 27,
full_name: "john doe",
username: "john",
is_active: true
};
const secondMockReturn = {
id: 28,
full_name: "jane doe",
username: "jane",
is_active: false
};
jest.spyOn(myApi, 'getUsers')
.mockResolvedValueOnce(firstMockReturn) // will return to firstMockReturn object firstly
.mockResolvedValueOnce(secondMockReturn); // will return to secondMockReturn object secondly
let baseDom = render(<Users />)
expect(await baseDom.findByText("true")).toBeInTheDocument();
fireEvent.click(await baseDom.findByTestId("refresh-button")); //to second api call
expect(await baseDom.findByText("false")).toBeInTheDocument();
})
推荐阅读
- python - Python 从 QTablewidget 中检索 QComboBox
- javascript - JS如何清除setInterval,不允许setInterval重复?
- java - 如何在 Java 中查找所有驱动器的类型、总空间、可用空间和可用空间?
- python - 如何使用动态变量创建图
- xml - SAPUI5 双向绑定到 XMLModel,按钮自定义数据属性不更新模型
- jquery - 使用 jQuery 填充输入标签,然后通过模型绑定提交到 ASP.NET Core
- python - Redis-py:run_in_thread 事件处理程序在几个小时后停止被调用
- java - NGINX URI 与周期代理通行证问题
- git - “Pop all as unstaged”会覆盖或合并以前的 pull 吗?
- excel - 验证类型时出现类型不匹配错误