如何测试使用Jest和Enzyme随时间更新的React组件?

Ani*_*ail 1 javascript reactjs jestjs enzyme

我有这个React组件

export class Timer extends Component {

constructor(props) {
    super(props);
    this.state = {i : props.i};
}

componentDidMount(){
    this.decrementCounter();
}

decrementCounter(){
    if(this.state.i < 1){
        return;
    }
    setTimeout(() => {
        this.setState({i : this.state.i - 1})
        this.decrementCounter()}, 1000);
}

render(){
    return <span>{this.state.i}</span>
}}
Run Code Online (Sandbox Code Playgroud)

我想表达一个这样的测试

jest.useFakeTimers();
it('should decrement timer ', () => {
    const wrapper = shallow(<Timer i={10} />);
    expect(wrapper.text()).toBe("10");
    jest.runOnlyPendingTimers();
    expect(wrapper.text()).toBe("9");
});
Run Code Online (Sandbox Code Playgroud)

目前是第一次预期通过,但第二次失败

Expected value to be (using ===):
      "9"
    Received:
      "10"
Run Code Online (Sandbox Code Playgroud)

我该如何正确测试这个组件?

hin*_*nok 8

使用完整渲染API,mount(...)

完整的DOM渲染非常适用于您拥有可能与DOM API交互的组件的情况,或者可能需要整个生命周期才能完全测试组件(即componentDidMount等)

你可以用mount()而不是shallow()

import React from 'react';
import { mount, /* shallow */ } from 'enzyme';
import Timer from './index';

describe('Timer', () => {
    it('should decrement timer ', () => {
        jest.useFakeTimers();

        const wrapper = mount(<Timer i={10} />);
        expect(wrapper.text()).toBe("10");
        jest.runOnlyPendingTimers();
        expect(wrapper.text()).toBe("9");

        jest.useRealTimers();
    });
});
Run Code Online (Sandbox Code Playgroud)

或者您可以传递其他对象shallow来检测它以运行生命周期方法

options.disableLifecycleMethods :( Boolean [optional]):如果设置为true,则不在组件上调用componentDidMount,并且在setProps和setContext之后不调用componentDidUpdate.

const options = {
  lifecycleExperimental: true,
  disableLifecycleMethods: false 
};

const wrapper = shallow(<Timer i={10} />, options);
Run Code Online (Sandbox Code Playgroud)

我测试了它.有用.

hinok:~/workspace $ npm test

> c9@0.0.0 test /home/ubuntu/workspace
> jest

 PASS  ./index.spec.js (7.302s)
  Timer
    ? should decrement timer  (28ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.162s
Ran all test suites.
Run Code Online (Sandbox Code Playgroud)