У меня есть компонент под названием «Список комментариев», список комментариев получает все комментарии, кроме this.props.posts
, который поступает из контейнера панели инструментов.
Компонент <CommentList/>
вызывается в компоненте <PostList/>
, оттуда он передает {post.Comments}
в качестве реквизита для
Мой вопрос: как мне правильно протестировать <CommentList/>
Компонент учитывая, что он использует селектор избыточности, api call et c.
Вот поток.
1) контейнер панели инструментов содержит реквизиты для this.props.post
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
addContent,
addTitle,
createPostInit,
deleteCommentInit,
initCommentUpdates,
deletePostInit,
dislikePostInit,
getPostsInit,
likePostInit,
notificationInit,
postCommentInit,
} from "../actions/postActions";
import Dashboard from "../components/dashboard/dashboard";
import { getBodyError, getIsNotified, getNotification, getPopPosts, getPosts, getTitleError, getUser, postContent, title } from "./../selectors/selectors";
const mapDispatchToProps = (dispatch: any) => ({
getPostsInit: () => dispatch(getPostsInit()),
initCommentUpdates: () => dispatch(initCommentUpdates()),
notificationInit: () => dispatch(notificationInit()),
likePost: (id: number) => dispatch(likePostInit(id)),
addTitle: (data: string) => dispatch(addTitle(data)),
addContent: (data: string) => dispatch(addContent(data)),
postCommentInit: (commentData: object) => dispatch(postCommentInit(commentData)),
dislikePost: (id: number) => dispatch(dislikePostInit(id)),
deletePostInit: (id: number, userId: number) => dispatch(deletePostInit(id, userId)),
deleteComment: (id: number, postId: number, userId: number) => dispatch(deleteCommentInit(id, postId, userId)),
createPostInit: (postData: object) => dispatch(createPostInit(postData)),
});
const mapStateToProps = createStructuredSelector({
posts: getPosts(),
popPosts: getPopPosts(),
user: getUser(),
isNotified: getIsNotified(),
titleError: getTitleError(),
bodyError: getBodyError(),
title: title(),
postContent: postContent(),
notification: getNotification(),
});
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard);
this.props.posts сопоставляется, а post.Commments передается в комментарийList prop
postList.tsx
{post.Comments.length > 0 ? (
<Fragment>
<Typography style={{ padding: "10px 0px", margin: "20px 0px" }}>Commments</Typography>
<CommentList user={currentUser} deleteComment={props.deleteComment} userId={post.userId} postId={post.id} comments={post.Comments} />
{/* if show more hide show more button and show show less comments button */}
</Fragment>
) : (
<Grid item={true} sm={12} lg={12} style={{ padding: "30px 0px" }}>
<Typography>No Commments Yet</Typography>
</Grid>
)}
CommentList. tsx
import Button from "@material-ui/core/Button";
import Divider from "@material-ui/core/Divider";
import Grid from "@material-ui/core/Grid";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import Typography from "@material-ui/core/Typography";
import OurListItem from "../../common/OurListItem";
import DeleteOutlineOutlinedIcon from "@material-ui/icons/DeleteOutlineOutlined";
import moment from "moment";
import React, { Fragment, useState } from "react";
export default function CommentList(props: any) {
const [showMore, setShowMore] = useState<Number>(3);
const [showLessFlag, setShowLessFlag] = useState<Boolean>(false);
const showComments = (e) => {
e.preventDefault();
setShowMore(12);
setShowLessFlag(true);
};
const showLessComments = (e) => {
e.preventDefault();
setShowMore(3);
setShowLessFlag(false);
};
return (
<Grid>
{props.comments.slice(0, showMore).map((comment, i) => (
<div key={i}>
<List style={{ paddingBottom: "20px" }}>
<OurListItem>
<Typography color="primary" align="left">
{comment.comment_body}
</Typography>
{comment.gifUrl && (
<div style={{ display: "block" }}>
<img width="100%" height="300px" src={`${comment.gifUrl}`} />
</div>
)}
</OurListItem>
{props.user && props.user.user && comment.userId === props.user.user.id ? (
<Typography style={{ display: "inline-block", float: "right" }} align="right">
<span style={{ cursor: "pointer" }} onClick={() => props.deleteComment(comment.id, props.postId, comment.userId)}>
<DeleteOutlineOutlinedIcon style={{ margin: "-5px 0px" }} color="primary" /> <span>Delete</span>
</span>
</Typography>
) : null}
<Typography style={{ padding: "0px 0px" }} variant="caption" align="left">
{comment.author.username}
</Typography>
<Typography style={{ fontSize: "12px" }} variant="body1" align="left">
{moment(comment.createdAt).calendar()}
</Typography>
<Divider variant="fullWidth" component="li" />
</List>
</div>
))}
<Fragment>
{props.comments.length > 3 && showLessFlag === false ? (
<Button onClick={(e) => showComments(e)} variant="outlined" component="span" color="primary">
Show More Comments
</Button>
) : (
<Fragment>
{props.comments.length > 3 && (
<Button onClick={(e) => showLessComments(e)} variant="outlined" component="span" color="primary">
Show Less Comments
</Button>
)}
</Fragment>
)}
</Fragment>
</Grid>
);
}
Как бы я правильно протестировал этот компонент с помощью redux, учитывая, что я не получаю его из redux, вот мой подход,
CommentList.test.tsx
import React from "react";
import CommentList from "./CommentList";
import Grid from "@material-ui/core/Grid";
import { createShallow } from "@material-ui/core/test-utils";
import toJson from "enzyme-to-json";
const props = {
comments: [
{
userId: 1,
id: 1,
comment_body: "delectus aut autem",
author: {
username: "Bill",
},
},
{
userId: 2,
id: 2,
comment_body: "delectus aut autem",
author: {
username: "Bill",
},
},
{
userId: 3,
id: 3,
comment_body: "delectus aut autem",
author: {
username: "Bill",
},
},
],
};
describe("Should render <CommentList/>", () => {
let wrapper;
let shallow;
beforeEach(() => {
shallow = createShallow();
wrapper = shallow(<CommentList {...props} />);
});
it("should render <CommentList/>", () => {
expect(wrapper.find(Grid)).toHaveLength(1);
});
it("should snap <CommentList/> component", () => {
// expect(toJson(wrapper)).toMatchSnapshot();
});
});