使用酶反应测试组件WillReceiveProps

时间:2017-03-23 18:48:51

标签: unit-testing reactjs material-ui jestjs enzyme

我将使用酶测试生命周期功能,包括componentWillReceiveProps。

在其他任何事情之前,我的组件应该被包裹materialUi styles并与redux连接。 否则,渲染函数中会出现错误,因为我使用了包括FlatButton在内的material-ui组件。

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或其他必要部分。

如何设置/更改MyComponent的道具以便我可以测试componentWillReceiveProps?

2 个答案:

答案 0 :(得分:9)

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

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(...);
});

答案 1 :(得分:-1)

如果你想测试MyComponent,你应该

const wrapper = mount(MyComponent);

像提供商这样的其他东西不是MyComponent的一部分,所以不应该包含在它的单元测试中。