尝试使用主题测试样式化组件时出错
Posted
技术标签:
【中文标题】尝试使用主题测试样式化组件时出错【英文标题】:Error trying to test Styled Components with Theme 【发布时间】:2021-11-16 15:06:31 【问题描述】:对于使用主题的样式化组件,我无法通过单元测试。我做错了什么?
失败 src/components/Button/spec.js ● 控制台
控制台错误 错误:未捕获 [TypeError:无法读取未定义的属性“primary1”]
Header.js
import React from "react";
import Container, Wrap, Logo, Image from "./HeaderStyles";
import logo from "../../assets/graphics/logo.png";
const Header = () =>
return (
<Container data-test="headerComponent">
<Wrap>
<Logo>
<Image data-test="logoImg" src=logo />
</Logo>
</Wrap>
</Container>
);
;
export default Header;
HeaderStyles.js
import styled from "styled-components";
export const Container = styled.header`
display: block;
width: 100%;
max-height: 85px;
margin: 0 auto;
padding: 0 10px;
background: $(props) => props.theme.colors.primary1; ;
`;
export const Wrap = styled.div`
display: relative;
width: 100%;
height: 100%;
margin: 0 auto;
max-width: 980px;
`;
export const Logo = styled.div`
display: block;
max-width: 120px;
left: 10px;
top: 50%;
-webkit-transform: translateY(-50%);
--moz-transform: translateY(-50%);
transform: translateY(-50%);
`;
export const Image = styled.img`
max-width: 70%;
margin-top: 9rem;
`;
export const Title = styled.h1`
color: $(props) => props.theme.colors.primary1;
`;
default.js
const theme =
// Temp fonts
fonts:
title: "Space Grotesk, sans-serif",
main: "Space Grotesk, sans-serif",
,
// Colors for layout
colors:
primary1: "#606060FF",
background1: "#D6ED17FF",
accent1: "hsl(34.9,98.6%,72.9%)",
button: "hsl(205.1,100%,36.1%)",
background2: "hsl(232.7,27.3%,23.7%)",
,
// Breakpoints for responsive design
breakpoints:
sm: "screen and (max-width: 640px)",
md: "screen and (max-width: 768px)",
lg: "screen and (max-width: 1024px)",
xl: "screen and (max-width: 1280px)",
,
;
export default theme;
spec.js
import "jest-styled-components";
import React from "react";
import Adapter from "enzyme-adapter-react-16";
import shallow, configure from "enzyme";
import Header from "./Header";
import toJson from "enzyme-to-json";
import theme from "../../themes/default";
import findByTestAtrr, renderWithTheme from "../../../utils/utils";
import Container, Image, Logo, Wrap from "./HeaderStyles";
configure( adapter: new Adapter() );
const setUp = (props = ) =>
const component = shallow(<Header theme=theme ...props></Header>);
return component;
;
describe("Header Component", () =>
let component;
beforeEach(() =>
component = setUp();
);
describe("Container Block", () =>
it("renders correctly with theme", () =>
const tree = renderWithTheme(<Container></Container>).toJSON();
expect(tree).toMatchSnapshot();
);
);
);
spec.js.snap
exports[`Header Component Container Block renders correctly with theme 1`] = `
.c0
display: block;
width: 100%;
max-height: 85px;
margin: 0 auto;
padding: 0 10px;
background: #606060FF;
<header
className="c0"
/>
`;
utils.js
import React from "react";
import theme from "../src/themes/default";
import TestRenderer from "react-test-renderer";
import ThemeProvider from "styled-components";
export const findByTestAtrr = (component, attr) =>
const wrapper = component.find(`[data-test='$attr']`);
return wrapper;
;
export const checkProps = (component, expectedProps) =>
const propsErr = checkPropTypes(
component.propTypes,
expectedProps,
"props",
component.name
);
return propsErr;
;
export const renderWithTheme = (component) =>
return TestRenderer.create(
<ThemeProvider theme=theme>component</ThemeProvider>
);
;
theme.js
import React from "react";
import ThemeProvider from "styled-components";
import PropTypes from "prop-types";
import theme from "../themes/default";
import GlobalStyles from "./globals";
const Theme = ( children ) => (
<ThemeProvider theme=theme>
<GlobalStyles />
children
</ThemeProvider>
);
Theme.propTypes =
children: PropTypes.element.isRequired,
;
export default Theme;
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import store from "./redux/store";
import Provider from "react-redux";
import Theme from "./styles/theme";
ReactDOM.render(
<React.StrictMode>
<Provider store=store>
<Theme>
<App />
</Theme>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
【问题讨论】:
【参考方案1】:Header 应该将 props 传递给需要它们的特定组件,例如 Container
。
const Header = ( theme, ...props ) =>
return (
<Container theme=theme data-test="headerComponent">
<Wrap>
<Logo>
<Image data-test="logoImg" src=logo />
</Logo>
</Wrap>
</Container>
);
;
虽然根据错误
失败 src/components/Button/spec.js ● 控制台
控制台错误 错误:未捕获 [TypeError:无法读取未定义的属性“primary1”]
似乎问题出在您的Button
组件中。可能是类似的问题。
【讨论】:
以上是关于尝试使用主题测试样式化组件时出错的主要内容,如果未能解决你的问题,请参考以下文章