reactjs - 使用 enzyme/jest 关闭后,reactstrap 模态中的内容继续存在

标签 reactjs testing jestjs enzyme reactstrap

我正在尝试使用 enzyme 和开 Jest 进行一些测试,当我打开模态时一切正常,例如模态中的输入字段不存在,当我尝试使用

expect(wrapper.find("input")).toHaveLength(0);

并且在我使用

打开模式后确实存在
const edit = wrapper.find("Button.update-button");
edit.simulate("click");
expect(wrapper.find("input")).toHaveLength(2);

一切正常(包括打开后模态状态变为真)。但是当我关闭模态时,状态被正确关闭,但是当我尝试时模态内容(例如模态中的输入框和按钮)仍然存在:

expect(wrapper.find("input")).toHaveLength(0);

由于模式关闭,我仍然有 2 个不应该存在的输入字段。

这是我正在尝试测试的组件的代码是否有帮助:

/*
    Artefact Component displays just UI for the Artefact itself and it's information.
*/

import React, { Component } from "react";

import DeleteArtefact from "../DeleteArtefact";
import UpdateArtefact from "../UpdateArtefact";

import {
    Card,
    CardImg,
    CardTitle,
    CardBody,
    ButtonGroup,
    Button,
    CardFooter
} from "reactstrap";

class Artefact extends Component {
    // Initialise State
    state = {
        updatemodal: false,
        deletemodal: false
    };

    // Toggle function for toggling modal open/close
    toggleUpdate = () => {
        this.setState({
            updatemodal: !this.state.updatemodal
        });
    };

    toggleDelete = () => {
        this.setState({
            deletemodal: !this.state.deletemodal
        });
    };

    prepareUpdateState = () => {
        this.props.editUpdate(this.props.artefact);
        this.toggleUpdate();
    };

    render() {
        const {
            artefact,
            onChange,
            onUpdateClick,
            editUpdate,
            onDeleteClick
        } = this.props;
        return (
            <Card>
                <CardImg
                    src={artefact.img}
                    alt={`Image for Artefact ${artefact.name}`}
                />
                <CardBody>
                    <CardTitle>
                        <h6>{artefact.name}</h6>
                    </CardTitle>
                </CardBody>
                <CardFooter>
                    <ButtonGroup>
                        <Button
                            className="update-button"
                            color="dark"
                            onClick={this.prepareUpdateState}
                        >
                            Edit
                        </Button>
                        <Button
                            className="delete-button"
                            color="dark"
                            onClick={this.toggleDelete}
                        >
                            Delete
                        </Button>
                    </ButtonGroup>
                    <UpdateArtefact
                        artefact={artefact}
                        onChange={onChange}
                        onUpdateClick={onUpdateClick}
                        editUpdate={editUpdate}
                        toggle={this.toggleUpdate}
                        modal={this.state.updatemodal}
                    />
                    <DeleteArtefact
                        _id={artefact._id}
                        onDeleteClick={onDeleteClick}
                        toggle={this.toggleDelete}
                        modal={this.state.deletemodal}
                    />
                </CardFooter>
            </Card>
        );
    }
}

export default Artefact;

这是具有我要测试的模式的 UpdateArtefact 组件:

/*
    UpdateArtefact Component is a child Component of ArtefactGallery and
    creates a new Artefact by using functions onChange() and updateClick() 
    and editUpdate() which are passed as props from ArtefactGallery and 
    passes state back up and makes api calls using axios.
*/

import React, { Component } from "react";
import {
    Button,
    Modal,
    ModalHeader,
    ModalBody,
    Form,
    FormGroup,
    Label,
    Input
} from "reactstrap";

class UpdateArtefact extends Component {
    // Passes state up to ArtefactGallery component and updates the artefact.
    onSubmit = e => {
        e.preventDefault();
        this.props.onUpdateClick(this.props.artefact._id);
        this.props.toggle();
    };

    // Sets state in ArtefactGallery to the initial values of the artefact
    // to prepare for any edits to be made in the case that some fields have
    // no change, so that there are no null fields.
    prepareUpdateState = () => {
        this.props.editUpdate(this.props.artefact);
        this.props.toggle();
    };

    render() {
        const { artefact } = this.props;
        return (
            <div style={{ marginLeft: "1rem" }}>
                <Modal isOpen={this.props.modal} toggle={this.props.toggle}>
                    <ModalHeader toggle={this.props.toggle}>
                        Edit Artefact
                    </ModalHeader>
                    <ModalBody>
                        <Form onSubmit={this.onSubmit}>
                            <FormGroup>
                                <Label>Artefact</Label>
                                <Input
                                    type="text"
                                    name="name"
                                    id="artefactName"
                                    defaultValue={artefact.name}
                                    onChange={this.props.onChange}
                                />
                                <Label>Image</Label>
                                <Input
                                    type="text"
                                    name="img"
                                    id="artefactImg"
                                    defaultValue={artefact.img}
                                    onChange={this.props.onChange}
                                />
                                <Button
                                    className="modal-submit-button"
                                    color="dark"
                                    style={{ marginTop: "2rem" }}
                                    block
                                >
                                    Submit
                                </Button>
                            </FormGroup>
                        </Form>
                    </ModalBody>
                </Modal>
            </div>
        );
    }
}

export default UpdateArtefact;

所以基本上我只想知道模态内容仍然被 enzyme 吸收的原因是什么以及如何解决这个问题。我试过到处搜索,但找不到答案,所以我猜我遗漏了一些明显的东西。

最佳答案

看,你的组件没有像

那样使用条件渲染
{someFlag && <SomeElement>}

但只需传递 isOpen 属性:

<Modal isOpen={this.props.modal} toggle={this.props.toggle}>

所以 Modal 可能只是隐藏了它的 props.childreninput 被保留了。

作为一种解决方法,您可以针对 ModalComponentYouHaveRendered.props().isOpen 进行验证,而不是检查 input 的数量

关于reactjs - 使用 enzyme/jest 关闭后,reactstrap 模态中的内容继续存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58098484/

相关文章:

javascript - 无法读取我的 API 或特定 API [React.js/Node.js/Axios/Fetch]

reactjs - 如何处理 React-Intl 消息的多次使用?

c# - 通过 API 测试测量 C# .net 代码覆盖率

javascript - 更新到 jest 24 后 transformIgnorePatterns 不工作

node.js - 我遗漏了一些关于 .env 的信息,你能给我解释一下吗?

javascript - 单击按钮时如何将按钮的值添加到文本区域?

javascript - 如何用 jest --watch 运行回调

c# - 为什么我的单元测试在不运行测试的情况下成功完成?

Reactjs - Jest 快照测试嵌套 redux "connected"组件

javascript - 为什么我在 Jest 中得到 "TextEncoder is not defined"?