使用酶反应测试 componentWillReceiveProps

React test componentWillReceiveProps using enzyme

我要测试生命周期函数,包括使用酶的 componentWillReceiveProps。

首先,我的组件应该被包装 materialUi styles 并与 redux 连接。 否则render函数会有bug,因为我用了material-ui组件包括FlatButton.

const wrapper = mount(
      <MuiThemeProvider muiTheme={muiTheme}>
         <Provider store={store}>
            <MemoryRouter>
               <MyComponent />
            </MemoryRouter>
         </Provider>
      </MuiThemeProvider>)

// absolutely fail
wrapper.find(MyComponent).setProps({ something })
expect(MyComponent.prototype.componentWillReceiveProps.calledOnce).toBe(true)

所以问题是我不能将 setProps() 用于 MyComponent,因为酶不允许应用非根组件。 我无法通过更改道具来测试 componentWillReceiveProps 或其他必要部分。

如何 set/change MyComponent 的 props 以便我可以测试 componentWillReceiveProps?

如果你想测试 MyComponent,你应该

const wrapper = mount(MyComponent);

Provider 等其他东西不是 MyComponent 的一部分,因此不应包含在它的单元测试中。

最好单独测试您的组件。问题是 material-ui 使用 React context 传递它的 props。您可以通过这种方式指定组件的上下文:

import React from 'react';
import { mount } from 'enzyme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

const wrapper = mount(
  <MyComponent />,
  {
    context: {
      muiTheme: getMuiTheme(),
    },
    childContextTypes: {
      muiTheme: React.PropTypes.object.isRequired,
    }
  }
);

您需要隔离组件的另一件事是删除 <Provider>。与其测试连接的组件,不如尝试按照 Redux 文档中描述的方式测试组件本身:Testing Connected Components

很快 - 导出组件和连接的组件,然后通过传递道具测试组件。具有导出的组件示例:

import { connect } from 'react-redux'

// Use named export for unconnected component (for tests)
export class MyComponent extends Component { /* ... */ }

// Use default export for the connected component (for app)
export default connect(mapStateToProps)(MyComponent)

您现在可以像这样在测试文件中导入未修饰的组件:

import { MyComponent } from './MyComponent';

最终测试可能是这样的:

import React from 'react';
import { mount } from 'enzyme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import { MyComponent } from './MyComponent';

test('test component', () => {
  const wrapper = mount(
    <MyComponent />,
    {
      context: {
        muiTheme: getMuiTheme(),
      },
      childContextTypes: {
        muiTheme: React.PropTypes.object.isRequired,
      }
    }
  );

  // Test something
  const p = wrapper.find(...);
  expect(...).toEqual(...);

  // Change props
  wrapper.setProps({foo: 1});

  // test again
  expect(...).toEqual(...);
});