I have a task to test React component that dependent of BrowserRouter
component somewhere in the upper level. As far as I know BrowserRouter
passes route object into props of any child, grandchild etc.
Component:
import React, { Component } from 'react';
import Program from './Program';
export default class Programs extends Component {
constructor() {
super();
this.state = {
programs: [
/** example */
{ id: 10, name: 'Golden Knights' },
{ id: 20, name: 'Silver Lords' },
{ id: 30, name: 'Wooden Kings' },
],
};
}
render() {
const { programs } = this.state;
return (
<ul className="programs">{/*<-- add class "att-programs"*/}
{
programs.map(
program => <Program
key={program.id}
program_id={program.id}
program_name={program.name}
/>,
)
}
</ul>
);
}
}
When I try to test this component independently, I get an error: Cannot read property 'route' of undefined
. To workaround this problem, I wrap my element into MemoryRouter
component and my test looks following:
import React from 'react';
import renderer from 'react-test-renderer';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import Programs from '../../src/components/Programs';
describe('<Programs />', () => {
it('Renders list for any child from state', () => {
const wrapper = mount(<MemoryRouter><Programs /></MemoryRouter>);
const programs = wrapper.find(Programs);
expect(programs.length).toBe(1);
programs.setState({
programs: [
{ id: 1, name: 'qwe' },
{ id: 2, name: 'asd' },
{ id: 3, name: 'zxc' },
],
});
expect(wrapper.find('li').length).toBe(3);
expect(wrapper.find('a[href="/player/1"]').length).toBe(1);
});
});
Now I have another problem: ReactWrapper::setState() can only be called on the root
Please help me figure out how do I mock router but stay able to define setState
on the testing component?
Aucun commentaire:
Enregistrer un commentaire