как выполнить модульное тестирование компонента, основанного на редуксе - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть компонент под названием «Список комментариев», список комментариев получает все комментарии, кроме 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();
    });
});

1 Ответ

2 голосов
/ 07 февраля 2020

Мой вопрос заключается в том, как бы я правильно протестировал Компонент, учитывая, что он использует селектор избыточности, вызов API и т. Д. c.

Я не вижу, чтобы это было правдой в любом месте. Компонент не полагается и не знает о Redux, он только получает реквизит (который вы можете высмеять в своих тестах).

Как бы я правильно протестировал этот компонент с помощью redux, учитывая, что я его не получаю Из редукса, вот мой подход

Вы не - это тестирование деталей реализации. Вы можете протестировать сами редукторы, но лучший способ проверить это - не ie объединить их.

На мой взгляд, вы пытаетесь протестировать ваши редукторы, используя этот компонент, не обязательно сам компонент, чтобы проверить сам компонент, работает просто отлично.

Или чтобы проверить все это вместе, вы должны посмотреть на тесты E2E.

...