繁体   English   中英

使用 Jest 和 Enzyme 测试 React 组件中的去抖动功能

[英]Testing debounced function in React component with Jest and 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>
    );
  }
}

我盘算了一下,去抖功能测试应该是非常相似的一个非去抖,而是用setTimeoutPromise (与expect中断言.then.finally )。 在尝试了采用这两种想法的多种测试变体之后,我不再那么确定了。 有任何想法吗?

注意:这个问题的答案也适用于lodash.throttle ,因为它只是一个包装debounce

Lodash的debounce是一个怪物,并在测试中需要一些特殊的处理,因为它不仅使用setTimeout()但它也:

  • 递归调用setTimeout() :这意味着调用jest.runAllTimers()来模拟setTimeout将导致无限递归错误,因为模拟的setTimeout setTimeout()同步执行,直到它用完任务,这里不是这种情况。

  • 使用Date API :Jest v25 及以下仅模拟计时器函数(例如setTimeoutsetInterval )而debounce使用setTimeoutDate所以我们需要模拟它们。

您如何解决此问题取决于您使用的是哪个版本的笑话。

对于 Jest 25 及以下版本:

使用另一个库来模拟Date对象。 在这个例子中,我将使用jest-date-mock advanceBy()

jest.useFakeTimers()

await act(async () => {
  triggerDebounced()
  advanceBy(DEBOUNCED_TIME + 1000) // forward Date
  jest.advanceTimersByTime(DEBOUNCED_TIME) // forward setTimeout's timer
})

玩笑版本 26:

Jest版本 26为假定时器引入了现代模式,它模拟Date和定时器功能,这是一个选择加入的功能,所以为了使用它,你需要在测试运行之前添加jest.useFakeTimers('modern')

jest.useFakeTimers("modern")

await act(async () => {
  triggerDebounced()
  jest.advanceTimersByTime(DEBOUNCED_TIME)
})

玩笑版本 27+:

根据这个PR ,Jest v27 将默认使用现代实现,因此我们不需要明确指定它。

jest.useFakeTimers()

await act(async () => {
  triggerDebounced()
  jest.advanceTimersByTime(DEBOUNCED_TIME)
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM