I'm using Enzyme, and we can actually use the example component given in the docs as a foundation for my question.
Let's assume this <Foo />
component uses a <Link>
component from ReactRouter and thus we need to wrap it in a <MemoryRouter>
for testing.
Herein lies the problem.
it('puts the lotion in the basket', () => {
const wrapper = mount(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
wrapper.state('name') // this returns null! We are accessing the MemoryRouter's state, which isn't what we want!
wrapper.find(Foo).state('name') // this breaks! state() can only be called on the root!
})
So, not exactly sure how to access local component state when using <MemoryRouter>
.
Perhaps I'm performing an ignorant test? Is trying to get/set component state bad practice in testing? I can't imagine it is, as Enzyme has methods for getting/setting component state.
Just not sure how one is supposed to access the internals of a component wrapped in <MemoryRouter>
.
Any help would be greatly appreciated!
To create wrapper components, you'll first learn to use the rest and spread operators to collect unused props to pass down to nested components. Then you'll create a component that uses the built-in children component to wrap nested components in JSX as if they were HTML elements.
An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered: static getDerivedStateFromProps() shouldComponentUpdate() render()
Prop drilling refers to the process of sending props from a higher-level component to a lower-level component. To pass the props down from the topmost component, we must do something like this: However, prop drilling can become an issue in itself because of its repetitive code.
Components in React basically return a piece of JSX code that tells what should be rendered on the screen. In React, we mainly have two types of components: Functional Components: Functional components are simply javascript functions. We can create a functional component in React by writing a javascript function.
So it seems with the latest release of Enzyme there is a potential fix for this issue of accessing state on a child component.
Let's say we have <Foo>
(note the use of React Router's <Link>
)
class Foo extends Component {
state = {
bar: 'here is the state!'
}
render () {
return (
<Link to='/'>Here is a link</Link>
)
}
}
Note: The following code is only available in Enzyme v3.
Revisiting the test code, we are now able to write the following
it('puts the lotion in the basket', () => {
const wrapper = mount(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
expect(wrapper.find(Foo).instance().state).toEqual({
bar: 'here is the state!'
})
})
Using wrapper.find(Child).instance()
we are able to access Child
's state even though it is a nested component. In previous Enzyme versions we could only access instance
on the root. You can also call the setState
function on the Child
wrapper as well!
We can use a similar pattern with our shallowly rendered tests
it('puts the lotion in the basket shallowly', () => {
const wrapper = shallow(
<MemoryRouter>
<Foo />
</MemoryRouter>
)
expect(wrapper.find(Foo).dive().instance().state).toEqual({
bar: 'here is the state!'
})
})
Note the use of dive
in the shallow test, which can be run on a single, non-DOM node, and will return the node, shallow-rendered.
Refs:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With