如何有条件地测试样式组件和子元素?
How to test styled components conditionally and children elements?
我是单元测试的新手,我已经在文档、文章和 YT 视频上花费了大约 20-30 个小时,但仍然不明白如何实现这一点。基本上我想在这里测试 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);
});
我收到以下错误:
类型错误: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 的解释会更多!
我会尽可能详细地回答您的问题。
所以你有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(不过这只是个人喜好问题)。
我建议 jest 因为它有你需要的一切,比如间谍、匹配器等,还有一些额外的包可以让你的生活更轻松,就像在这种情况下。
所以为了用笑话测试你的 styled-components 你需要两个额外的包 react-test-renderer
(基本上将 React 组件转换成 js 对象)和 jest-styled-components
(这会给你一个名为 toHaveStyleRule 的额外匹配器,它将对您的目标有很大帮助。
安装了这 2 个包后,您要做的是首先导入它们:
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。测试点击事件
要测试点击事件,您需要一个间谍。如果您使用的是 jest,那么您已经拥有此功能,如果您使用的是 mocha,我想您可能需要一个额外的软件包,例如 sinon 或类似的软件包。
间谍会让你跟踪你的 updateState
函数发生了什么,所以当你测试点击事件时,你将传递一个间谍函数作为 updateState 属性的值。通过这种方式,当您模拟单击按钮时,您的间谍将被调用,然后您将能够像 "have you been called?" 一样向它提问,因此您将能够检查您调用的单击事件具有预期参数的 updateState 函数。
在 this link 中,您会发现您的示例(经过一些小的修改)可以正常工作,并且可以测试您想要检查的所有内容(不要注意依赖项出现在 package.json 文件,其中许多应该显示为开发依赖项,但出于某种原因,如果我这样做它不起作用,这可能是我在该工具中做错了什么)。
希望这个回答对您有所帮助。
我是单元测试的新手,我已经在文档、文章和 YT 视频上花费了大约 20-30 个小时,但仍然不明白如何实现这一点。基本上我想在这里测试 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);
});
我收到以下错误: 类型错误: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 的解释会更多!
我会尽可能详细地回答您的问题。
所以你有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(不过这只是个人喜好问题)。 我建议 jest 因为它有你需要的一切,比如间谍、匹配器等,还有一些额外的包可以让你的生活更轻松,就像在这种情况下。
所以为了用笑话测试你的 styled-components 你需要两个额外的包 react-test-renderer
(基本上将 React 组件转换成 js 对象)和 jest-styled-components
(这会给你一个名为 toHaveStyleRule 的额外匹配器,它将对您的目标有很大帮助。
安装了这 2 个包后,您要做的是首先导入它们:
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。测试点击事件
要测试点击事件,您需要一个间谍。如果您使用的是 jest,那么您已经拥有此功能,如果您使用的是 mocha,我想您可能需要一个额外的软件包,例如 sinon 或类似的软件包。
间谍会让你跟踪你的 updateState
函数发生了什么,所以当你测试点击事件时,你将传递一个间谍函数作为 updateState 属性的值。通过这种方式,当您模拟单击按钮时,您的间谍将被调用,然后您将能够像 "have you been called?" 一样向它提问,因此您将能够检查您调用的单击事件具有预期参数的 updateState 函数。
在 this link 中,您会发现您的示例(经过一些小的修改)可以正常工作,并且可以测试您想要检查的所有内容(不要注意依赖项出现在 package.json 文件,其中许多应该显示为开发依赖项,但出于某种原因,如果我这样做它不起作用,这可能是我在该工具中做错了什么)。
希望这个回答对您有所帮助。