【发布时间】:2020-03-12 14:16:39
【问题描述】:
我正在使用 Jest + Testing-Library/React 编写功能测试。经过几天的挠头,我发现当您使用.mockResolvedValue(...) 或.mockResolvedValueOnce(...) 时,模拟的范围不仅限于该测试...
import React from "react";
import { render, waitForElement } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import myApi from '../myApi';
jest.mock('../myApi'); // this will load __mocks__/myApi.js (see below)
import { wait } from '@testing-library/dom';
import App from "../components/App";
afterEach(() => {
jest.clearAllMocks();
});
describe("App", () => {
test("first test", async () => {
myApi.get.mockResolvedValueOnce('FOO');
// App will call myApi.get() once
const { container, getByText } = render(<App />);
await waitForElement(
() => getByText('FOO')
);
expect(myApi.get).toHaveBeenCalledTimes(1);
// This is going to "leak" into the next test
myApi.get.mockResolvedValueOnce('BAR');
});
test("second test", async () => {
// This is a decoy! The 'BAR' response in the previous test will be returned
myApi.get.mockResolvedValueOnce('FOO');
// App will call myApi.get() once (again)
const { container, getByText } = render(<App />);
// THIS WILL FAIL!
await waitForElement(
() => getByText('FOO')
);
expect(myApi.get).toHaveBeenCalledTimes(1);
});
});
__mocks__/myApi.js 是这样的:
export default {
get: jest.fn(() => Promise.resolve({ data: {} }))
};
我了解发生了什么:myApi 被导入到两个测试的共享范围中。这就是为什么.mockResolvedValue*“跨越”测试的原因。
什么是防止这种情况的正确方法?测试应该是原子的,而不是相互耦合的。如果我在first test 中触发另一个get 请求,它应该无法中断second test。那是臭!但正确的模式是什么?我正在考虑将 myApi 的不同“副本”克隆到本地测试范围中......但我担心这会变得很奇怪并导致我的测试信心下降。
我发现 this question 讨论了相同的主题,但只解释了为什么会发生这种情况,而不是讨论避免这种情况的正确模式。
package.json
"dependencies": {
"axios": "^0.18.1",
"moment": "^2.24.0",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "2.1.5",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^4.2.3",
"@testing-library/react": "^9.3.2",
"redux-mock-store": "^1.5.3",
"typescript": "^3.7.2"
}
【问题讨论】:
-
easypuppyApi.get来自哪里?你会分享App组件吗? -
@Teneff 抱歉,这是一个复制/粘贴错误。我修复了它,所以变量名现在是
myApi。 -
我认为
<App />的内容并不重要,因为我的问题是关于 Jest。我认为它只调用myApi.get()才重要,对吗?
标签: unit-testing jestjs integration-testing react-testing-library