TDB*_*TDB 7 javascript reactjs jestjs enzyme
我正在使用 Jest 和 Enzyme 测试 React 组件,并且很难测试去抖动函数是否被正确调用(或根本调用)。我已经简化了下面的组件代码(经过编辑以使代码更简单),此处链接到 codepen
// uses lodash debounce
class MyApp extends React.Component {
constructor(props) {
super()
this.state = {name: "initial value"};
this.debouncedFunction = _.debounce(this.debouncedFunction, 3000);
this.handleClick = this.handleClick.bind(this)
}
debouncedFunction () {
this.setState({name: "after delay, updated value"});
}
handleClick() {
this.debouncedFunction();
}
render() {
return (
<div>
<p>{this.state.name}</p>
<button onClick={this.handleClick}>
click for debounced function
</button>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为去抖动功能测试应该与非去抖动功能测试非常相似,但带有一个setTimeoutor Promise(expect在.thenor 中带有断言.finally)。在尝试了采用这两种想法的多种测试变体之后,我不再那么确定了。有任何想法吗?
Nea*_*arl 18
注意:这个答案也适用于, lodash.throttle因为它只是debounce.
Lodashdebounce是一个怪物,需要在测试中进行一些特殊处理,因为它不仅使用,setTimeout()而且还:
调用 递归:这意味着调用来模拟将导致无穷递归的错误,因为嘲笑同步执行,直到它运行的任务了,这是不是这里的情况。setTimeout() jest.runAllTimers()setTimeoutsetTimeout()
使用 API:Jest v25 及以下仅模拟计时器函数(例如, ),同时使用两者,因此我们需要模拟它们。Date setTimeoutsetIntervaldebouncesetTimeoutDate
您如何解决此问题取决于您使用的是哪个版本的笑话。
使用另一个库来模拟Date对象。在这个例子中,我将使用advanceBy()fromjest-date-mock
jest.useFakeTimers()
await act(async () => {
triggerDebounced()
advanceBy(DEBOUNCED_TIME + 1000) // forward Date
jest.advanceTimersByTime(DEBOUNCED_TIME) // forward setTimeout's timer
})
Run Code Online (Sandbox Code Playgroud)
Jest版本 26为假定时器引入了现代模式Date,它模拟和定时器功能,这是一个选择加入的功能,所以为了使用它,你需要jest.useFakeTimers('modern')在测试运行之前添加
jest.useFakeTimers("modern")
await act(async () => {
triggerDebounced()
jest.advanceTimersByTime(DEBOUNCED_TIME)
})
Run Code Online (Sandbox Code Playgroud)
根据这个PR,Jest v27 将默认使用现代实现,因此我们不需要明确指定它。
jest.useFakeTimers()
await act(async () => {
triggerDebounced()
jest.advanceTimersByTime(DEBOUNCED_TIME)
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4406 次 |
| 最近记录: |