-
-
Save a-h/21df0f432ae02a6dfed941debb0e5950 to your computer and use it in GitHub Desktop.
import React from 'react'; | |
import { shallow } from 'enzyme'; | |
const Item = text => <p>Item {text}</p>; | |
const Composition = ({ showB }) => ( | |
<p> | |
<Item text="A" /> | |
{showB && <Item text="B" />} | |
</p>); | |
describe('<Composition />', () => { | |
it('should render one item if showB is set to false', () => { | |
const wrapper = shallow(<Composition showB={false} />); | |
expect(wrapper.find(Item)).toHaveLength(1); | |
}); | |
it('should render two items if showB is set to true', () => { | |
const wrapper = shallow(<Composition showB />); | |
expect(wrapper.find(Item)).toHaveLength(2); | |
}); | |
}); |
import React from 'react'; | |
import { shallow } from 'enzyme'; | |
import { CircularProgress } from 'material-ui-next/Progress'; | |
const Composition = () => ( | |
<p> | |
<CircularProgress size={24} /> | |
</p>); | |
describe('<Composition />', () => { | |
it('should render a CircularProgress', () => { | |
const wrapper = shallow(<Composition />); | |
expect(wrapper.find(CircularProgress)).toHaveLength(1); | |
}); | |
}); |
import React from 'react'; | |
import { shallow } from 'enzyme'; | |
import { CircularProgress } from 'material-ui-next/Progress'; | |
import { withStyles } from 'material-ui-next/styles'; | |
import PropTypes from 'prop-types'; | |
const style = { | |
buttonProgress: { | |
position: 'absolute', | |
top: '50%', | |
left: '50%', | |
marginTop: -12, | |
marginLeft: -12, | |
}, | |
}; | |
const Composer = ({ | |
classes, | |
}) => ( | |
<p> | |
<CircularProgress size={24} className={classes.buttonProgress} /> | |
</p>); | |
Composer.propTypes = { | |
classes: PropTypes.object.isRequired, | |
}; | |
const Composition = withStyles(style)(Composer); | |
describe('<Composition />', () => { | |
it('should render a styled CircularProgress', () => { | |
const wrapper = shallow(<Composition />); | |
// Note the use of dive() because Composition is now wrapped by the withStyles higher order component. | |
expect(wrapper.dive().find(CircularProgress)).toHaveLength(1); | |
}); | |
}); |
import React from 'react'; | |
import { CircularProgress } from 'material-ui-next/Progress'; | |
import { createShallow } from 'material-ui-next/test-utils'; | |
import { withStyles } from 'material-ui-next/styles'; | |
import PropTypes from 'prop-types'; | |
const style = { | |
buttonProgress: { | |
position: 'absolute', | |
top: '50%', | |
left: '50%', | |
marginTop: -12, | |
marginLeft: -12, | |
}, | |
}; | |
const Composer = ({ | |
classes, | |
}) => ( | |
<p> | |
<CircularProgress size={24} className={classes.buttonProgress} /> | |
</p>); | |
Composer.propTypes = { | |
classes: PropTypes.object.isRequired, | |
}; | |
const Composition = withStyles(style)(Composer); | |
describe('<Composition />', () => { | |
const shallow = createShallow(); | |
it('should render CircularProgress', () => { | |
const wrapper = shallow(<Composition />); | |
// Still need to dive(). | |
expect(wrapper.dive().find(CircularProgress)).toHaveLength(1); | |
}); | |
}); |
import React from 'react'; | |
import { CircularProgress } from 'material-ui-next/Progress'; | |
import { mount } from 'enzyme'; | |
import { withStyles } from 'material-ui-next/styles'; | |
import PropTypes from 'prop-types'; | |
const style = { | |
buttonProgress: { | |
position: 'absolute', | |
top: '50%', | |
left: '50%', | |
marginTop: -12, | |
marginLeft: -12, | |
}, | |
}; | |
const Composer = ({ | |
classes, | |
}) => ( | |
<div> | |
<CircularProgress size={24} className={classes.buttonProgress} /> | |
</div>); | |
Composer.propTypes = { | |
classes: PropTypes.object.isRequired, | |
}; | |
const Composition = withStyles(style)(Composer); | |
describe('<Composition />', () => { | |
it('should render CircularProgress', () => { | |
const wrapper = mount(<Composition />); | |
// No longer need to dive(). | |
expect(wrapper.find(CircularProgress)).toHaveLength(1); | |
}); | |
}); |
Hi, I'm not sure I'm going to be of great help here - I have only ever used Redux for state management and use stateless functional components to populate the props of a component. The props of each styled component are accessible (I put together an example here: https://github.com/a-h/styled-test - run npx jest
to run the test) so deeper inspection isn't required.
Sounds like your code structure is already pretty fixed, but I'd consider restructuring to have stateless functional components to handle the presentation. Those components can be tested simply - e.g. "given a row count of 10, 10 rows are rendered", "when this button is clicked, the onClick prop is called". Then, I'd add a higher-order component that wraps the others. The tests here would be along the lines of "when this function is called, the prop passed to this component changes".
If you find a nice solution, I'd be interested to see it!
Thank you. I am testing button clicks, state and direct API calls, and I agree with you that I shouldn't test state and API to test what is rendered instead. Unfortunately I use react-Konva and the graph is quite complex, I didn't manage to test the rendering yet.
Thanks very much.
Hi,
I have changed my code to wrap my components with 'withStyles' and all my unit tests are now failing. Your example 05-simple-material-withstyles-using-mount.test.js matches what I am doing in my test:
In your test above how would you get the state of the CircularProgress object if it was also a styled component? And how would you get the wrapper instance to have access to Composition's public API?
I got it to work by calling children.first() like that:
But I have to manually edit 200+ unit tests, so I'm hoping I missed something simpler.
Thank you
Cl.