I've started using jest and enzyme recently. I'm writing simple code to learn jest & enzyme.
There is one test I can't pass. I've had this problem for a long time.
I don't understand why the first assertion below is okay while the second assertion below is not.
expect(component.find(CommentBox).dive().find('.comment-box').exists()).toBe(true);
expect(component.find(CommentList).dive().find('.comment-list').exists()).toBe(true);
These components are siblings.
<div>
<div>Hello World!</div>
<CommentBox />
<CommentList />
</div>
Could anyone please help me understand what I'm doing wrong?
Here are all related codes and log.
Test Result Log
FAIL src/__tests__/components/App.test.js
● App › shows a comment list
Method “dive” is only meant to be run on a single node. 0 found instead.
at ShallowWrapper.single (node_modules/enzyme/build/ShallowWrapper.js:1516:17)
at Object.<anonymous> (src/__tests__/components/App.test.js:38:57)
at Promise (<anonymous>)
at <anonymous>
App.test.js
import React, { Component } from 'react';
import { shallow, mount} from 'enzyme';
import App from '../../components/App';
jest.unmock('../../components/App');
import CommentBox from '../../components/CommentBox';
import ConnectedCommentList, { CommentList } from '../../components/CommentList';
describe('App', () => {
let component;
beforeEach(() => {
component = shallow(<App />);
});
//This test passes!
it('shows a comment box', () => {
expect(component.find(CommentBox).dive().find('.comment-box').exists()).toBe(true);
});
//This test fails!!
it('shows a comment list', () => {
expect(component.find(CommentList).dive().find('.comment-list').exists()).toBe(true);
})
});
App.js
import React, { Component } from 'react';
import CommentBox from './CommentBox';
import CommentList from './CommentList';
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div>Hello World!</div>
<CommentBox />
<CommentList />
</div>
)
}
}
export default App;
CommentList.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
const propTypes = {};
const defaultProps = {};
export const CommentList = (props) => {
const list = props.comments.map((comment) => {
return <li key={comment}>{comment}</li>
});
return (
<ul className="comment-list">
{list}
</ul>
)
};
function mapStateToProps(state) {
return {
comments: state.comments
}
}
CommentList.propTypes = propTypes;
CommentList.defaultProps = defaultProps;
export default connect(mapStateToProps)(CommentList);
Additional Info
I'm using shallow method instead of mount method because if I use mount method, then I get this error Invariant Violation: Could not find "store" in either the context or props of "Connect(CommentList)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(CommentList)".
instead.
JSX of CommentBox
<form onSubmit={this.handleSubmit} className="comment-box">
<textarea
value={this.state.comment}
onChange={this.handleChange}
/>
<button action="submit">Submit</button>
</form>
JSX of CommentList
<ul className="comment-list">
{list}
</ul>
UPDATE!
it('shows a comment list', () => {
console.log(component.debug());
})
I used debug method to see what enzyme is rendering. This is the result.
<div>
<div>
Hello World!
</div>
<CommentBox />
<Connect(CommentList) />
</div>
It seems that the problem occurs because it renders <Connect(CommentList)>
instead of <CommentList>
.
import ConnectedCommentList, { CommentList } from '../../components/CommentList';
But, in App.test.js, I import both ConnectedCommentList and regular CommentList and for the test, I use CommentList.
How can I make this test passes!?
component.find('CommentList').dive()
– Andreas KöberleCommentList
is wrapped into reduxconnect
. Will provide a solution after lunch. – Andreas Köberle