reactjs - Jest 测试库 - 多次调用以在点击事件上加载数据
问题描述
我正在尝试在 onClick fireEvent 上测试加载更多按钮调用,但在模拟单击以触发加载数据时遇到问题。
零件:
class Items extends Component {
// states
componentDidMount() {
this.getData()
}
getData() { ...
// get data from state - pagination # and data size
}
onLoadMore() {
// increment pagination & offset on states
this.getData()
}
render() {
return (
<div className='container'>
{items.map((item, i) => {
return (
<div className='item-box'>
// item info
</div>
)
}
)}
<button onClick={this.onLoadMore}>Load More</button>
</div>
)
}
}
测试:
it('load more data on load more button click', () => {
const Items = require('./default').default
// set initial load values: initVals (2 items)
// set second call values: secondVals (4 items)
Items.prototype.getData = jest.fn()
Items.prototype.getData.mockReturnValue(initVals)
Items.prototype.getData.mockReturnValue(secondVals)
const { container } = render(
<Items
fields={{ loadMore: true }}
/>
)
const button = screen.getByText('Load More')
fireEvent.click(button)
expect(container.querySelectorAll('.item-box').length).toBe(2)
expect(container.querySelectorAll('.item-box').length).toBe(4)
})
所以这只读取最后一次调用,找到 4 个项目。
.mockReturnValue()
多次调用只会给我最后一次调用,而不是连续调用。我知道我用错了,但我不知道运行它的顺序。我的目标是使用第一个值(加载 2 个项目)初始化组件,然后在单击时加载更多(4 个项目)。
帮助?
解决方案
我认为您需要调用mockReturnValueOnce
而不是mockReturnValue
,并且您肯定需要在单击事件之前移动您的第一个断言。另外,我认为您的第二个断言应该期望6
,而不是4
.
您的测试的操作顺序应该是:
- 设置模拟
- 渲染组件
- 在加载时断言初始值
- 模拟点击事件
- 单击后断言值。
这是一个演示此概念的简单示例:
// src/Demo.js
import React, { useState } from "react";
const Demo = ({ loadText }) => {
const [text, setText] = useState("");
return (
<div>
<button onClick={() => setText(loadText())}>Load</button>
<p data-testid="data">{text}</p>
</div>
);
};
export default Demo;
// src/Demo.test.js
import { fireEvent, render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Demo from "./Demo";
test("callbacks", () => {
const myMock = jest.fn();
myMock.mockReturnValueOnce(2);
myMock.mockReturnValueOnce(4);
render(<Demo loadText={myMock} />);
fireEvent.click(screen.getByRole("button"));
expect(screen.getByTestId("data")).toHaveTextContent("2");
fireEvent.click(screen.getByRole("button"));
expect(screen.getByTestId("data")).toHaveTextContent("4");
});
此外,您嘲笑此函数 ( Items.prototype.getData = jest.fn()
) 的方式对我来说似乎很奇怪。我建议您探索其他选项,例如(1)模拟 axios 或类似的库,(2)模拟一个 redux 存储,或(3)模拟你传递给这个组件的 props。
推荐阅读
- javascript - 错误类型错误:未定义。何时从服务中提供数据
- android - getSupportFragmentManager().findFragmentById(R.id.fragment_id) returns null
- node.js - 如何在我的节点 js 项目中添加 google AdSense
- node.js - Reactjs按ID删除项目
- node.js - Node.js 从快捷方式(或别名或引用)路径(或文件夹或目录)读取文件
- docker - Openproject Docker 重启 > 清理 OpenProject
- generics - 返回具有关联类型的特征
- python - 缩放到特定的 pyqgis 图层
- html - 调整浏览器窗口大小时如何缩小所有 HTML 元素
- swiftui - SwiftUI - 如何在 Swift 中使用结果