Reputation: 343
I have a HOC, adding some props to the component, for handling network requests and passing down data as prop. The following is a very simplified version of the HOC:
export const withTags = (Component) => {
class WithTags extends PureComponent {
getItems() {
return getTags({
search: this.state.searchTerm
})
.then((items) => this.setState({
items
}));
}
.
.
.
render() {
return (
<Component
{...this.props}
items={this.state.items}
getItems={this.getItems}
/>
);
}
}
return withTags;
}
Using enzyme
I can easily do something like:
it('should return tags', async () => {
const mockComponent = jest.fn(() => null);
const WithTagsComponent = withTags(mockComponent);
const wrapper = shallow(<WithTagsComponent />);
const res = await wrapper.props().getItems();
expect(res).toEqual(getTagsResponseMock);
expect(tagsApi.getTags).toHaveBeenCalledTimes(1);
expect(tagsApi.getTags).toHaveBeenCalledWith({
limit: PAGE_SIZE,
});
expect(wrapper.props().items).toEqual([tagFlowMock]);
});
But this approach won't work in React Testing Library, as we should test from the end-user's perspective, and not access props. So, how should I test such HOCs using React Testing Library?
Upvotes: 4
Views: 4711
Reputation: 2197
I think your test almost works fine but you need to replace two things.
Since you're manually calling getItems
here you could create a mock Component that would ideally do similar stuff as the components you plan to use with your HOC.
For example, this mock component coould have a button that when clicked would call getItems
and would also display items
.
const MockComponent = ({items, getItems}) => {
return (
<div>
<button data-testid="button" onClick={getItems}>Click me</button>
<ul>
{ items.map((item, index) => <li key={index}>{item}</li>) }
</ul>
</div>
)
Then in your test instead of manually calling getItems
:
const res = await wrapper.props().getItems();
you could do something like
fireEvent.click(getByTestId('button')
and then assert that your tagsApi was called and that your component displays correct items.
Upvotes: 1