使用酶反应测试 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(...);
});
我要测试生命周期函数,包括使用酶的 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(...);
});