I'm trying to learn Jest and Enzyme but I'm having a problem I can't find a solution to, this is my test.. it's not very good I know but I'm learning:
import * as apiMock from '../api';
const fakePostId = '1';
const fakePersona = 'Fake';
jest.mock('../api', () => {
return {
fetchAllComments: jest.fn(() => {
return [];
}),
filterComments: jest.fn(() => {
return [];
}),
createCommentObject: jest.fn(() => {
return [];
}),
};
});
test('checks if functions are called after didMount', () => {
const component = shallow(
<Comments postId={fakePostId} currentPersona={fakePersona} />
);
const spySetComments = jest.spyOn(
component.instance(),
'setCommentsFromLocalStorage'
);
component.instance().componentDidMount();
expect(spySetComments).toHaveBeenCalledTimes(1);
//Don't know why these are called 2! times, I can't see why removing componentDidMount makes it 0.
expect(apiMock.fetchAllComments).toHaveBeenCalledTimes(1);
expect(apiMock.filterComments).toHaveBeenCalledTimes(1);
}
The problem is toHaveBeenCalledTimes(1)
fails with reason:
Expected mock function to have been called one time, but it was called two times.
But I don't know why. setCommentsFromLocalStorage
only runs once, and that is the function that sohuld run from componentDidMount and execute these api calls once.
ReactComponent looks like this:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import CreateNewComment from './CreateNewComment';
import SingleComment from './SingleComment';
import * as api from '../api';
class Comments extends Component {
state = {
comments: []
};
componentDidMount() {
this.setCommentsFromLocalStorage();
}
setCommentsFromLocalStorage = (postId = this.props.postId) => {
const fetchedComments = api.fetchAllComments();
const comments = api.filterComments(fetchedComments, postId);
this.setState({ comments });
};
removeComment = commentId => {
api.removeComment(commentId);
this.setCommentsFromLocalStorage();
};
renderCommentList = (comments, currentPersona) =>
comments.map(comment => (
<SingleComment
{...comment}
currentPersona={currentPersona}
key={comment.id}
onClick={this.removeComment}
/>
));
render() {
return (
<div className="py-2">
<h2 className="text-indigo-darker border-b mb-4">Comments</h2>
{this.renderCommentList(this.state.comments, this.props.currentPersona)}
<CreateNewComment
postId={this.props.postId}
author={this.props.currentPersona}
updateComments={this.setCommentsFromLocalStorage}
/>
</div>
);
}
}
Comments.propTypes = {
postId: PropTypes.string.isRequired,
currentPersona: PropTypes.string.isRequired
};
export default Comments;