Jest Enzyme set memory of memoryRouter dependent

时间:2017-08-11 12:20:26

标签: javascript reactjs testing enzyme jest

我有一项任务是在上层某处测试依赖于BrowserRouter组件的React组件。据我所知BrowserRouter将路由对象传递给任何孩子,孙子等的道具。

组件:

import React, { Component } from 'react';
import Program from './Program';

export default class Programs extends Component {
  constructor() {
    super();
    this.state = {
      programs: [
        /** example */
        { id: 10, name: 'Golden Knights' },
        { id: 20, name: 'Silver Lords' },
        { id: 30, name: 'Wooden Kings' },
      ],
    };
  }

  render() {
    const { programs } = this.state;
    return (
      <ul className="programs">{/*<-- add class "att-programs"*/}
        {
          programs.map(
            program => <Program
              key={program.id}
              program_id={program.id}
              program_name={program.name}
            />,
          )
        }
      </ul>
    );
  }
}

当我尝试独立测试此组件时,出现错误:Cannot read property 'route' of undefined。要解决此问题,我将我的元素包装到MemoryRouter组件中,我的测试看起来如下:

import React from 'react';
import renderer from 'react-test-renderer';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';

import Programs from '../../src/components/Programs';

describe('<Programs />', () => {
  it('Renders list for any child from state', () => {

    const wrapper = mount(<MemoryRouter><Programs /></MemoryRouter>);
    const programs = wrapper.find(Programs);
    expect(programs.length).toBe(1);
    programs.setState({
      programs: [
        { id: 1, name: 'qwe' },
        { id: 2, name: 'asd' },
        { id: 3, name: 'zxc' },
      ],
    });

    expect(wrapper.find('li').length).toBe(3);
    expect(wrapper.find('a[href="/player/1"]').length).toBe(1);
  });
});

现在我有另一个问题:ReactWrapper::setState() can only be called on the root

请帮我弄清楚如何模拟路由器但能够在测试组件上定义setState

1 个答案:

答案 0 :(得分:2)

我建议不要直接更新组件的内部状态。哟是以某种方式操纵该状态的方式(或者你计划)。因此在测试期间使用这些机制。例如。您可能需要考虑通过wrapper.simulate("click")点击按钮并更改状态。之后,您可以验证状态转换是否正确。