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

时间:2019-05-27 22:21:42

标签: reactjs unit-testing enzyme styled-components

我是单元测试的新手,我已经在文档,文章和YT视频上花费了20到30个小时,但仍然无法理解如何实现这一目标。基本上我想在这里测试3件事:

  1. 确保该组件呈现3个组件
  2. 测试条件样式
  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);
});

我收到以下错误: TypeError:Enzyme :: 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;

任何帮助将不胜感激,关于ELI5的解释将更多!

1 个答案:

答案 0 :(得分:0)

我会尽力回答您的问题。

所以您有3个问题:

1。确保该组件呈现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);
});

但是您不能在代码中执行此操作,因为您没有导出MyButton组件。 我对这个问题的建议是,为MyButton组件创建一个文件,为ButtonsComponent组件创建另一个文件。通常,每个文件只有一个组件就更清楚了,单元测试也变得更加清晰。 然后,您将可以执行以下操作:

import { shallow } from "enzyme";
import React from "react";
import ButtonsComponent from "./ButtonsComponent";
import MyButton from "./MyButton"

it("renders three <MyButton /> components", () => {
  const wrapper = shallow(<ButtonsComponent />);
  expect(wrapper.find(MyButton)).to.have.lengthOf(3);
});

2。测试条件样式

我不知道您使用的是什么测试引擎(mocha,jest等),但是如果我必须选择一个测试引擎来测试React应用程序,我会选择Jest(不过这只是一个品味问题)。 我建议您开玩笑,因为它具有您所需的一切,例如间谍,匹配器等,还有一些其他软件包可以使您的生活更轻松,例如在这种情况下。

因此,要开玩笑地测试样式化组件,您将需要两个额外的包react-test-renderer(基本上将React组件转换为js对象)和jest-styled-components(这将给您一个额外的匹配器,名为toHaveStyleRule,将对您的目标大有帮助。

在安装了这两个软件包之后,首先要导入它们:

import renderer from "react-test-renderer";
import "jest-styled-components";

然后,您将组件转换为js对象:

const tree =
  renderer
  .create(<MyButton color="red">Test</MyButton>)
  .toJSON();

最后,您将要求为您为组件指定的属性应用期望的样式:

expect(tree).toHaveStyleRule("background-color", "red");

3。测试点击事件

要测试click事件,您需要一个间谍。如果您使用的是开玩笑,那么您已经拥有此功能,如果您使用的是摩卡咖啡,我想您可能需要一个额外的软件包,例如sinon或类似软件包。

间谍程序将使您能够跟踪updateState函数发生的情况,因此,在测试单击事件时,您将传递一个间谍函数作为updateState属性的值。这样,当您模拟单击按钮时,您的间谍将被调用,然后您就可以向其询问问题,例如“您被叫过吗?”,因此,您将能够检查单击事件。用期望的参数调用updateState函数。

this link中,您将发现您的示例(进行了一些小的修改)可以正常运行,并且可以对所有要检查的内容进行测试(不要注意package.json文件中依赖项的显示位置) ,其中许多应该显示为开发依赖项,但由于某些原因,如果我这样做不起作用,则可能是我在该工具中做错了。

希望这个答案对您有所帮助。