【问题标题】: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")
);




【问题讨论】:

    标签: reactjs jestjs themes enzyme styled-components


    【解决方案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 组件中。可能是类似的问题。

    【讨论】:

      猜你喜欢
      • 2019-02-16
      • 2019-07-01
      • 1970-01-01
      • 2021-08-06
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多