Reactjs 如何有条件地测试样式化组件和子元素?

Reactjs 如何有条件地测试样式化组件和子元素?,reactjs,unit-testing,enzyme,styled-components,Reactjs,Unit Testing,Enzyme,Styled Components,我是单元测试新手,我花了大约20-30个小时在文档、文章和YT视频上,但仍然不知道如何实现这一点。基本上,我想在这里测试3件事: 确保此组件渲染3个组件 测试条件样式 测试单击事件 到目前为止,对于第一件事,如果我尝试: import { shallow } from "enzyme"; import React from "react"; import ButtonsComponent, { SchedButton } from "./ButtonsComponent"; it("rende

我是单元测试新手,我花了大约20-30个小时在文档、文章和YT视频上,但仍然不知道如何实现这一点。基本上,我想在这里测试3件事:

  • 确保此组件渲染3个组件
  • 测试条件样式
  • 测试单击事件
  • 到目前为止,对于第一件事,如果我尝试:

    import { shallow } from "enzyme";
    import React from "react";
    import ButtonsComponent, { SchedButton } from "./ButtonsComponent";
    
    it("renders three <MyButton /> components", () => {
      const wrapper = shallow(<ButtonsComponent />);
      expect(wrapper.find(MyButton)).to.have.lengthOf(3);
    });
    
    从“酶”导入{shall};
    从“React”导入React;
    导入按钮组件,{SchedButton}来自“/buttonComponent”;
    它(“呈现三个组件”,()=>{
    常量包装器=浅();
    expect(wrapper.find(MyButton)).to.have.lengthOf(3);
    });
    
    我得到以下错误: TypeError:Ezyme::Selector需要字符串、对象或组件构造函数

    我不知道如何测试另外两件事,我看到了一些例子,但我不知道如何使它们适应我的特殊情况,因为它们似乎并不完全测试我要做的事情

    这是我的组件的简化版本:

    import React from "react";
    import styled from "styled-components";
    
    const MyButton = styled.button`
      background: ${props =>
        props.color ? theme.palette.secondary.dark : "#e6e6e6"};
      color: ${props => (props.color ? "white" : "#737373")};
    `;
    
    const ButtonsComponent = ({ currentState, updateState }) => {
      const handleClick = event => {
        updateState(event.target.value);
      };
    
      return (
        <div>
          <MyButton
            value="Button 1"
            onClick={handleClick}
            color={currentState === "Button 1" ? "#1fbd45" : ""}
          >
            Button 1
          </MyButton>
          <MyButton
            value="Button 2"
            onClick={handleClick}
            color={currentState === "Button 2" ? "#1fbd45" : ""}
          >
            Button 2
          </MyButton>
    
          <MyButton
            value="Button 3"
            onClick={handleClick}
            color={!currentState || currentState === "Button 3" ? "#1fbd45" : ""}
          >
            Button 3
          </MyButton>
        </div>
      );
    };
    
    export default ButtonsComponent;
    
    expect(tree).toHaveStyleRule("background-color", "red");
    
    从“React”导入React;
    从“样式化组件”导入样式化;
    const MyButton=styled.button`
    背景:${props=>
    props.color?theme.palete.secondary.dark:#e6“};
    颜色:${props=>(props.color?“白色”:“#737373”);
    `;
    常量按钮组件=({currentState,UpdateEstate})=>{
    const handleClick=事件=>{
    updateState(event.target.value);
    };
    返回(
    按钮1
    按钮2
    按钮3
    );
    };
    导出默认按钮组件;
    

    非常感谢您的任何帮助,一个ELI5解释将是如此之多

    我会尽量详细地回答你的问题

    所以你有3个问题:

    一,。确保此组件渲染3个组件

    你的测试几乎是正确的。错误是您正在执行以下操作:
    wrapper.find(MyButton)
    而不是
    wrapper.find('MyButton')
    。 要执行
    wrapper.find(MyButton)
    您需要先导入MyButton组件,这样应该可以:

    import { shallow } from "enzyme";
    import React from "react";
    import ButtonsComponent, { MyButton } from "./ButtonsComponent";
    
    it("renders three <MyButton /> components", () => {
      const wrapper = shallow(<ButtonsComponent />);
      expect(wrapper.find(MyButton)).to.have.lengthOf(3);
    });
    
    然后将组件转换为js对象:

    const tree =
      renderer
      .create(<MyButton color="red">Test</MyButton>)
      .toJSON();
    
    三,。测试单击事件

    要测试点击事件,您需要一个间谍。如果你使用的是jest,你已经有了这个功能,如果你使用的是mocha,我想你可能需要一个额外的软件包,比如sinon或类似的软件包

    spy将允许您跟踪
    updateState
    函数发生的情况,因此当您测试单击事件时,您将传递一个spy函数作为updateState属性的值。通过这种方式,当您模拟单击按钮时,您的spy将被调用,然后您将能够向它询问问题,如“您被调用了吗?”,因此,您将能够检查单击事件时是否使用预期的参数调用updateState函数

    在中,您将发现您的示例(经过一些小的修改)正在运行,并且对所有您想要检查的内容进行测试(不要注意package.json文件中依赖项出现的位置,它们中的许多应该显示为开发人员依赖项,但由于某种原因,如果我这样做了,它就不起作用,这可能是我在该工具中做错的事情)


    我希望这个答案能对你有所帮助。

    非常感谢你提供的详细答案。它实际上帮助很大。是的,忘了说我在开玩笑了。
    const tree =
      renderer
      .create(<MyButton color="red">Test</MyButton>)
      .toJSON();
    
    expect(tree).toHaveStyleRule("background-color", "red");