如何有条件地测试样式化组件和子元素? [英] How to test styled components conditionally and children elements?

查看:62
本文介绍了如何有条件地测试样式化组件和子元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to unit testing and I've spent some 20-30 hours in docs, articles and YT videos but still can't make sense of how to achieve this. Basically I want to test 3 things here:


  1. 确保该组件呈现3个组件

  2. 测试条件样式

  3. 测试点击事件

到目前为止,对于第一件事,如果我尝试这样做:

So far, for the 1st thing, if I try to do:

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需要一个字符串,对象,或组件构造器

I get the following error: TypeError: Enzyme::Selector expects a string, object, or Component Constructor

我不知道如何测试其他两件事,我已经看到了一些示例,但我不知道如何使它们适应我的特定情况,因为他们似乎并没有完全测试我正在尝试做的事情。

And I don't have any good idea how to test the other two things, I've seen some examples but I don't understand how to adapt them to my particular situation since they don't seem to be testing exactly what I'm trying to do.

这是我组件的简化版本:

This is a simplifed version of my component:

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的解释将更多!

Any help is greatly appreciated, an ELI5 explanation would be so much more!

推荐答案

我将尝试尽可能详细地回答您的问题。

I will try to answer your questions as detailed as possible.

所以您有3问题:

1。确保该组件呈现3个组件

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

Your test was almost correct. The error was that you were doing: wrapper.find(MyButton) instead of wrapper.find('MyButton'). To do wrapper.find(MyButton) you need to import the MyButton component first, so something like this should work:

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组件创建另一个文件。通常,每个文件只有一个组件就更清楚了,单元测试也变得更加清晰。
然后,您将可以执行以下操作:

But you can't do this in your code because you are not exporting the MyButton component. My advise regarding this question would be that you create a file for MyButton component and another file for ButtonsComponent component. In general it is much more clear to have one component per file, and unit testing becomes clearer as well. Then you will be able to do something like this:

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。测试条件样式

我不知道您使用的是哪种测试引擎(摩卡,笑话等),但是如果我必须选择一个进行测试的话一个React应用程序,我会选择Jest(尽管这只是一个口味问题)。
我建议您开个玩笑,因为它拥有您所需的一切,例如间谍,火柴等,还有一些其他软件包可以使您的生活更轻松,例如在这种情况下。

I do not know what testing engine (mocha, jest, etc) you are using, but if I had to choose one to test a React app I would choose Jest (this is just a matter of taste though). I suggest jest because it have everything you would need, like spies, matchers, etc, and there are also some additional packages that will make your life easier, like in this case.

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

So to test your styled-components with jest you will need two extra packages react-test-renderer (which basically converts a React components into a js object) and jest-styled-components (which will give you an extra matcher named toHaveStyleRule that will help you a lot with your goal).

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

With those 2 packages installed what you will do is, first import them:

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

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

Then you will convert your component to a js object:

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

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

And finally you will ask for the style you are expecting to have applied with the properties you specified for your component:

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

3。测试点击事件

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

To test the click event you will need a spy. If you are using jest you already have this feature, if you are using mocha I think you will probably need an extra package like sinon or similar.

间谍会让您跟踪 updateState 函数会发生什么,因此在测试单击事件时,您将传递一个间谍函数作为updateState属性的值。这样,当您模拟单击按钮时,您的间谍将被调用,然后您就可以向其询问问题,例如您被叫过吗?,因此,您可以检查单击事件,

The spy will let you track what happen to your updateState function, so when you are testing the click event you will pass a spy function as value of updateState prop. In this way when you simulate the click on your button your spy would be invoked and then you will be able to ask question to it like "have you been called?", as a result you will be able to check that on click event you invoke the updateState function with the expected params.

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

In this link you will find your example (with a few small modifications) working and with tests for all the things you wanted to check (do not pay attention to the place where the dependencies appear in package.json file, many of them should appear as dev dependencies but for some reason if I do that it does not work, it is probably something I am doing wrong in that tool).

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

I hope this answer helps you.

这篇关于如何有条件地测试样式化组件和子元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆