我有一个设置道具的测试,以观察组件中的一些变化。唯一的复杂因素是我将渲染的元素包装在<Provider>
中,因为在树的下方有一些连接的组件。
我通过
进行渲染const el = () => <MyComponent prop1={ prop1 } />;
const wrapper = mount(<Provider store={store}>{ el() }</Provider>);
然后我尝试使用以下内容来观察一些更改:
wrapper.setProps({ /* new props */ });
// expect()s etc.
问题是setProps()
没有在包装组件上正确设置道具。我认为这是因为<Provider>
实际上没有通过道具,因为它不是HoC。有没有更好的方法来测试这个,而不仅仅是更改本地范围的道具变量和重新渲染?
答案 0 :(得分:0)
您应该只在被包装的组件或父级上调用setProps
。
一个好的经验法则是你的测试应该只测试一个组件(父组件),所以不允许用酶设置儿童道具。
如果您的子组件进一步向下,我们需要满足(通过Provider和context)的商店依赖关系,那么这很好,但这些子组件应该有自己独立的测试。
这是鼓励您为setProps
上的更改编写测试的地方。
如果您发现自己正在为容器或连接器编写测试,那么您实际上只想验证子组件是否正在接收正确的道具和/或状态。例如:
import { createMockStore } from 'mocks'
import { shallwo } from 'enzyme'
// this component exports the redux connection
import Container from '../container'
const state = { foo: 'bar' }
let wrapper
let wrapped
let store
beforeEach(() => {
store = createMockStore(state)
wrapper = shallow(<Container store={store} />)
wrapped = wrapper.find('MyChildComponent')
})
it('props.foo', () => {
const expected = 'bar'
const actual = wrapped.prop('foo')
expect(expected).toEqual(actual)
})
另一个提示是,它有助于理解浅和mount之间的区别,因此您不必在测试中不必要地模仿儿童的依赖关系,这里的最佳答案是一个很好的阅读:
When should you use render and shallow in Enzyme / React tests?
答案 1 :(得分:0)
这是使用setProps
import { Provider } from 'react-redux';
const renderComponent = properties => mount(
React.createElement(
props => (
<Provider store={store}>
<IntlProvider locale="en" defaultLocale="en" messages={messages}>
<Router>
<MyComponent {...props} />
</Router>
</Provider>
),
properties))
然后进行测试
it('should set some props', () => {
const renderedComponent = renderComponent(props);
renderedComponent.setProps({ /* some props */ } });
expect(true).toBe(true);
})
答案 2 :(得分:0)
将组件包装在提供程序中后,我遇到了同样的问题。我所做的是,我在子代上使用了setProps而不是组件本身。
这是我在测试套件中的组件的示例:
let component, connectedComponent;
component = () => {
store = configureMockStore()(myStore);
connectedComponent = mount(
<Provider >
<MyComponent store={store} params={{xyz: 123}} />
</Provider>);};
但是在测试本身中,我做到了:
connectedComponent.setProps({children: <MyComponent params={{}} />});
答案 3 :(得分:0)
我想提供与上述解决方案类似的解决方案。
使用问题中定义的安装包装,
const wrapper = mount(<Provider store={store}>{ el() }</Provider>);
然后,在测试本身上,您可以简单地克隆子级,即Provider
中的子级组件,然后调用setProps
:
it('should get do x and y', () => {
wrapper.setProps({
children: cloneElement(wrapper.props().children as ReactElement, { ...props }),
});
// handle the rest below
});
如果您使用的是JavaScript,则无需包含as ReactElement
类型的断言。
对于使用TypeScript的用户,有必要将其声明为ReactElement
,因为ReactChild
的类型可能为ReactElement<any> | ReactText
。由于我们确定Provider中呈现的元素是ReactElement
,因此最快的解决方案是使用类型断言。