reactjs - 笑话模拟工厂不适用于模拟类
问题描述
我正在尝试模拟一个服务类来测试一个 React 组件。但是 jest.mock 的模块工厂不起作用。
搜索组件:
import React, { useState } from "react";
import SearchService from "../../services/SearchService";
export default function Search() {
const [searchResults, setSearchResults] = useState([]);
function doSearch() {
const service = new SearchService();
service.search().then(setSearchResults);
}
return (
<div className="component-container">
<div>
<button onClick={doSearch}>search</button>
</div>
{searchResults.map((result) => (
<div key={result}>{result}</div>
))}
</div>
);
}
搜索服务:
export default class SearchService {
search = function () {
return new Promise((resolve) => {
setTimeout(
() => resolve(["result 1", "result 2", "result 3", "result 4"]),
1000
);
});
};
}
测试文件:
import React from "react";
import { screen, render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { act } from "react-dom/test-utils";
import Search from "../features/search/Search";
jest.mock("../services/SearchService", () => {
return jest.fn().mockImplementation(() => {
return { search: jest.fn().mockResolvedValue(["mock result"]) };
});
});
test("Search", async () => {
render(<Search />);
const button = screen.getByRole("button");
expect(button).toBeDefined();
act(() => {
userEvent.click(button);
});
await screen.findByText("mock result");
});
这与Jest 文档示例的结构相同。在上面的代码中,我通过 jest.mock 的模块工厂参数传递了模拟实现。但它不起作用。当我记录新的 SerchService() 时,我得到“mockConstructor {}”,当我运行测试时,它抛出错误“service.search 不是函数”。
当我将测试文件更改为...
import React from "react";
import { screen, render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { act } from "react-dom/test-utils";
import Search from "../features/search/Search";
import SearchService from "../services/SearchService";
jest.mock("../services/SearchService");
test("Search", async () => {
SearchService.mockImplementation(() => {
return { search: jest.fn().mockResolvedValue(["mock result"]) };
});
render(<Search />);
const button = screen.getByRole("button");
expect(button).toBeDefined();
act(() => {
userEvent.click(button);
});
await screen.findByText("mock result");
});
它有效......我有点理解为什么它以第二种方式工作,我猜它就像使用 jest.spyOn 一样。我无法理解的是为什么它不适用于第一种方法。
我做错了什么?如何使用 jest.mock 模拟模块实现而不在每个测试中调用 .mockImplementation?
解决方案
我发现文档有问题,工厂需要返回一个函数()(不是箭头函数),所以我将模拟更改为以下内容并且它可以工作:
jest.mock("../services/SearchService.js", () => {
return function () {
return { search: jest.fn().mockResolvedValue(["mock result"]) };
};
});
在这篇文章中找到。
推荐阅读
- ios - Swift 二次曲线路径不以曲线闭合
- javascript - 如何使图表水平滚动
- c# - klocwork 错误 - 对函数“GetTokenResponseAsync”的调用可能为空,并将被取消引用
- node.js - Mocha ingores 测试,如何启动所有
- javascript - Javascript不适用于 IE 11
- jenkins - 在 jenkins 文件中设置环境变量
- r - 你能不把`print()`用管道传递给ggplot而不用`()`包装吗
- go - gorilla/websocket 设置读取限制?
- javascript - Jquery后更新/更改表格单元格文本
- html - 有没有办法在 Bootstrap 4 中仅在移动设备上禁用 Jumbotron?