【问题标题】:onClick passing in tests, but failing when physically clickedonClick 通过测试,但在物理单击时失败
【发布时间】:2019-12-25 19:32:35
【问题描述】:

这是我的Accordion 组件

import React, {Component, Fragment} from 'react';
import ArrowTemplate from "./ArrowTemplate";
import ContentTemplate from "./ContentTemplate";

class Accordion extends Component {
    constructor(props) {
        super(props);
        this.state = {isAccordionExpanded: false};
        this.foldAccordion = this.foldAccordion.bind(this);
        this.expandAccordion = this.expandAccordion.bind(this);
    }

    expandAccordion() {
        console.log(1);
        this.setState({isAccordionExpanded: true});
    }

    foldAccordion() {
        console.log(2);
        this.setState({isAccordionExpanded: false});
    }

    render() {
        const {state} = this;
        const {isAccordionExpanded} = state;

        if (isAccordionExpanded === false) {
            return (
                <Fragment>
                    <ArrowTemplate
                        aria={`aria-expanded="true"`}
                        onClick={this.expandAccordion}
                        direction={'down'}
                        color={'black'}
                        styles={'background:yellow'}
                    />
                </Fragment>
            );
        } else if (isAccordionExpanded === true) {
            return (
                <Fragment>
                    <ArrowTemplate
                        aria={`aria-expanded="true"`}
                        onClick={this.foldAccordion}
                        color={'black'}
                        direction={'up'}
                    />
                    <ContentTemplate/>
                </Fragment>
            );
        }
    }
}

export default Accordion;

这是ArrowTemplate

import React from "react";
import BlackDownArrowSVG from './svgs/black-down-arrow.svg';
import WhiteDownArrowSVG from './svgs/white-down-arrow.svg';
import styled from 'styled-components';
import PropTypes from 'prop-types';

ArrowTemplate.propTypes = {
    color: PropTypes.string.isRequired,
    direction: PropTypes.string.isRequired,
    styles: PropTypes.string,
    aria: PropTypes.string.isRequired,
};

function ArrowTemplate(props) {
    const {color, direction, styles, aria} = props;
    const StyledArrowTemplate = styled.img.attrs({
        src: color.toLowerCase() === "black" ? BlackDownArrowSVG : WhiteDownArrowSVG,
        aria,
    })`
        ${direction.toLowerCase() === "up" ? "translate: rotate(180deg)" : ""}
        ${styles}
`;
    return <StyledArrowTemplate/>;
}

export default ArrowTemplate;

这是我的相关测试

describe("<Accordion/>",
    () => {
        let wrapper;
        beforeEach(
            () => {
                wrapper = shallow(
                    <Accordion/>
                );
            }
        );
        it('should have one arrow at start',
            function () {
                expect(wrapper.find(ArrowTemplate)).toHaveLength(1);
            }
        );
        it('should change state onClick',
            function () {
                wrapper.find(ArrowTemplate).simulate("click");
                expect(wrapper.state().isAccordionExpanded).toEqual(true);
            }
        );
        it('should call FoldAccordionMock onClick',
            function () {
                wrapper.setState({isAccordionExpanded: true});
                wrapper.find(ArrowTemplate).simulate("click");
                expect(wrapper.state().isAccordionExpanded).toEqual(false);
            }
        );
        it('should display content if isAccordionExpanded = true',
            function () {
                wrapper.setState({isAccordionExpanded: true});
                expect(wrapper.find(ContentTemplate).exists()).toEqual(true);
            }
        );
        it('should hide content if isAccordionExpanded = false',
            function () {
                expect(wrapper.find(ContentTemplate).exists()).toEqual(false);
            }
        );
    }
);

所以问题是当我调整测试时 .simulate(click) 似乎工作,并且所有测试都通过了。但是当我自己单击该组件时,什么也没有发生。甚至没有控制台日志。将 onClick 更改为 onClick={()=&gt;console.log(1)} 也不起作用。有什么想法吗?

【问题讨论】:

  • 你必须在你的元素上实际写上onClick。试试这个,&lt;StyledArrowTemplate onClick={props.onClick}/&gt;

标签: javascript reactjs unit-testing jestjs styled-components


【解决方案1】:

StyledArrowTemplate 内部组件对onClick 一无所知。
ArrowTemplate 不知道 onClick 是什么意思,它只是另一个任意的道具。

但是,如果您按照@ravibagul91 在他们的评论中所说的那样做,您应该再次传递 onClick,StyledArrowTemplate 可能知道onClick 的含义。

所以只需添加&lt;StyledArrowTemplate onClick={props.onClick}/&gt;

【讨论】:

    【解决方案2】:

    手风琴组件

    import React, { Component, Fragment } from "react";
    import ArrowTemplate from "./ArrowTemplate";
    import ContentTemplate from "./ContentTemplate";
    
    class Accordion extends Component {
      constructor(props) {
        super(props);
        this.state = { isAccordionExpanded: false };
      }
    
      toggleAccordian = () => {
        console.log(1);
        this.setState({ isAccordionExpanded: !isAccordionExpanded });
      };
    
      render() {
        const { state } = this;
        const { isAccordionExpanded } = state;
    
        if (isAccordionExpanded) {
          return (
            <Fragment>
              <ArrowTemplate
                aria={`aria-expanded="true"`}
                onClick={() => this.toggleAccordian()}
                color={"black"}
                direction={isAccordionExpanded ? "up" : "down"}
                styles={`background:{isAccordionExpanded ? 'yellow' : ''}`}
              />
              <ContentTemplate />
            </Fragment>
          );
        }
      }
    }
    
    export default Accordion;
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多