在componentDidMount中开玩笑的酶测试方法失败,但控制台显示它正在工作

时间:2019-01-07 21:09:37

标签: reactjs jestjs enzyme

在我的componentDidMount()内部,如果有几个函数返回true,则我正在呼叫this.loadData()。我的代码中都有控制台日志,这些日志向我证明了它正在调用该函数,但是Jest则说根本没有调用它。

请注意我的console.log以下步骤。

  1. componentDidMount
  2. 向下钻取评估为真
  3. 响应不为空

componentDidMount()

componentDidMount() {
    console.log('componentDidMount');

    if(props.drilldown) {
        console.log('drilldown');

        // emptyObject is a helper function that makes sure
        // modifiedState.response !== {}

        if(!emptyObject(modifiedState.response)) {
            console.log('response not empty');

            this.loadData(modifiedState.response, modifiedState.lastUpdated);
        }
    }
}

调用loadData()时,我的测试输出中将显示另外3个console.log

  1. loadData被称为
  2. data已通过
  3. updated已通过

loadData

loadData(data, updated) {
    console.log('loadData');
    console.log(data);
    console.log(updated);

    ... a bunch of other stuff here that doesn't matter
}

在单元测试中,我将按以下方式设置要传递给loadData的值。

  1. data的评估结果应为{ table: [{}] }
  2. updated的评估结果应为'Wed Dec 26 2018 13:26:03 GMT-0500'

单元测试

it('component mounts as expected', () => {

    const modifiedState = {
        ...parentState,
        lastUpdated: 'Wed Dec 26 2018 13:26:03 GMT-0500',
        response: { table: [{}] }
    }

    const wrapper = shallow(
        <Chart
            chart='testChart'
            comparison='testComparison'
            drilldown={true}
            parentState={modifiedState} />
    );

    const loadData = jest.spyOn(wrapper.instance(), 'loadData');

    expect(loadData).toHaveBeenCalledWith({ table: [{}] }, 'Wed Dec 26 2018 13:26:03 GMT-0500');
    expect(loadData).toHaveBeenCalledTimes(1);

    wrapper.unmount();
  });

运行测试时,控制台输出显示loadData was not called及其所抱怨的行是

expect(loadData).toHaveBeenCalledWith({ table: [{}] }, 'Wed Dec 26 2018 13:26:03 GMT-0500');

但是,如果继续滚动,您会看到我所有的console.log都被呼叫了相应的信息。这告诉我它实际上正在工作,但是使用Jest / Enzyme的东西不正确。

请注意,我在componentDidMount()内还有其他4个功能可以通过。

运行测试时控制台日志输出

 FAIL  src/components/Common/Chart.test.js
  ● Drilldown Chart › component mounts as expected

    expect(jest.fn()).toHaveBeenCalledWith(expected)

    Expected mock function to have been called with:
      [{"table": [{}]}, "Wed Dec 26 2018 13:26:03 GMT-0500"]

    But it was not called.

      at Object.fit (src/components/Common/Chart.test.js:140:22)
          at new Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:182:7)

  Chart
    ○ skipped 1 test
  Drilldown Chart
    ✕ component mounts as expected (19ms)
    ○ skipped 11 tests
  Dashboard Chart
    ○ skipped 2 tests

Test Suites: 1 failed, 1 total
Tests:       1 failed, 14 skipped, 15 total
Snapshots:   0 total
Time:        6.515s

Ran all test suites matching "src/components/Common/Chart.test.js".

  console.log src/components/Common/Chart.jsx:45
    componentDidMount

  console.log src/components/Common/Chart.jsx:75
    drilldown

  console.log src/components/Common/Chart.jsx:77
    response not empty

  console.log src/components/Common/Chart.jsx:134
    loadData

  console.log src/components/Common/Chart.jsx:135
    { table: [ {} ] }

  console.log src/components/Common/Chart.jsx:136
    Wed Dec 26 2018 13:26:03 GMT-0500

1 个答案:

答案 0 :(得分:2)

马修·赫伯斯特在事物的顺序上是正确的。

您可以改为:

it('component mounts as expected', () => {

    const modifiedState = {
        ...parentState,
        lastUpdated: 'Wed Dec 26 2018 13:26:03 GMT-0500',
        response: { table: [{}] }
    }

    const wrapper = shallow(
        <Chart
            chart='testChart'
            comparison='testComparison'
            drilldown={true}
            parentState={modifiedState} />,
        { disableLifecycleMethods: true }
    );
    const instance = wrapper.instance()
    const loadData = jest.spyOn(instance, 'loadData');
    instance.componentDidMount()

    expect(loadData).toHaveBeenCalledWith({ table: [{}] }, 'Wed Dec 26 2018 13:26:03 GMT-0500');
    expect(loadData).toHaveBeenCalledTimes(1);

    wrapper.unmount();
  });

在这里,我使用{ disableLifecycleMethods: true }禁用了生命周期方法。然后,我在设置间谍后手动调用componentDidMount

有点俗气,但是可以用。