在 React with Enzyme 中测试去抖动方法

IT技术 reactjs lodash jestjs enzyme
2021-05-05 14:57:37
//Component
import _ from 'lodash';

constructor(props) {
  super(props);
  this.onScroll = _.debounce(::this.onScroll, 100);
}

onScroll() {
  //some code
}

//Test
it('onScroll', () => {
  const component = shallow(<Component />);
  component.instance().onScroll(); //Dosn't call method 
})

我使用酶作为渲染组件,使用 lodash 作为debounce. 怎么打电话component.instance().onScroll()

2个回答

TL; 博士; 用于在模拟计时器进行测试lolex时及时推进_.debounce

我已经准备好描述几种用 jest byuseFakeTimers来模拟计时器的方法advanceTimersByTime但它没有用。

一段时间后,我发现它适用于_.throttle但不适用于_.debounce. 然后我发现Jest 的 repo 中报告问题还有专门的错误报告“_.debounce 打破了假计时器”,我没有看到它已经解决(忽略它的状态并检查那里的最后评论)。

根据 veeeeeery 的详细解释 _.debounce不仅可以放setTimeout而且还可以检查时差。所以我们也应该嘲笑Date.nowJestjest.runOnlyPendingTimersjest.advanceTimersByTime不这样做。

所以对于简单的组件,如

function Debounced({onClick}) {
    return <button onClick={_debounce(onClick,500)}>Click Me</button>;  
}

下一个测试已通过:

let clock = lolex.install();
const onClick = jest.fn();
const wrapper = shallow(<Debounced onClick={onClick} />);
const button = wrapper.find('button').at(0);

button.simulate('click');
button.simulate('click');
button.simulate('click');

clock.tick(510);
expect(onClick).toHaveBeenCalledTimes(1);
clock.uninstall();

PS 确定你可以运行lolex.install()clock.uninstall()beforeEach/afterEach

您可以返回一个Promise并在其中断言。

it('onScroll', () => {
    const component = shallow(<Component />);
    return new Promise(resolve=> {
       component.instance().onScroll();
       expect(mockOnScrollFunction).toHaveBeenCalledTimes(1);
       setTimeout(resolve,101);
   }
}