mardi 16 mars 2021

Test React component with hooks and styled components

I have a problem with testing component which one using hooks and styled components. I've got problems with snapshot when state "isSmallMenu" and "isHiddenMenu" is true.

import React, { useState } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import Content from './Content/Content';
import { options } from './utils';

const Sidebar = (props) => {
  const [activeTab, setActiveTab] = useState(null);
  const [isSecondLevel, setIsSecondLevel] = useState(false);
  const [isSmallMenu, setIsSmallMenu] = useState(false);
  const [isHiddenMenu, setIsHiddenMenu] = useState(false);
  const { redirect } = props;

  const handleTabClick = (tabData) => {
    if (tabData.content.length) {
      setActiveTab(tabData);
      setIsSecondLevel(true);
    } else {
      redirect();
    }
  };

  const handleBack = () => {
    setActiveTab(null);
    setIsSecondLevel(false);
  };

  const getOptions = () =>
    (isSecondLevel && activeTab)
      ? options.content.find((item) => item.id === activeTab.id).content
      : options.content;

  return (
    <Wrapper
      isSecond={isSecondLevel}
      isSmallMenu={isSmallMenu}
      isHiddenMenu={isHiddenMenu}
      data-test="Sidebar"
    >
      <Content
        {...props}
        data-test="Content"
        isHiddenMenu={isHiddenMenu}
        setIsHiddenMenu={setIsHiddenMenu}
        isSmallMenu={isSmallMenu}
        setIsSmallMenu={setIsSmallMenu}
        handleBack={handleBack}
        options={getOptions()}
        handleTabClick={handleTabClick}
        activeTab={activeTab}
        isSecond={isSecondLevel}
        name={(isSecondLevel && activeTab) ? activeTab.name : ''}
      />
    </Wrapper>
  );
};

Sidebar.propTypes = {
  redirect: PropTypes.func,
};

export default Sidebar;

const Wrapper = styled.div`
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
    0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  overflow-y: auto;
  width: ${({ isSmallMenu, isHiddenMenu }) =>
    isSmallMenu || isHiddenMenu ? '80px' : '260px'};
  height: ${({ isHiddenMenu }) => (isHiddenMenu ? '80px' : '100vh')};
  background-color: ${({ isSecond, theme }) =>
    isSecond ? 'rgba(176, 190, 197, 0.5)' : theme.palette.grayDark};
`;

Coverage shows that i need to test code using variables in styled components. When I try to change states and then make snapshot everything is ok but lines are not correctly tested.

  it('Should apply correct styles for small mode', () => {
    const getProps = () => findByTestAttr(component, 'Sidebar').props();
    let props = getProps();
    props.children.props.setIsSmallMenu(true);
    props = getProps();
    expect(component).toMatchSnapshot();
  });
  it('Should apply correct styles for hidden mode', () => {
    const getProps = () => findByTestAttr(component, 'Sidebar').props();
    let props = getProps();
    props.children.props.setIsHiddenMenu(true);
    props = getProps();
    expect(component).toMatchSnapshot();
  });
  it('Should apply correct styles for second mode', () => {
    const getProps = () => findByTestAttr(component, 'Sidebar').props();
    let props = getProps();
    props.children.props.setIsHiddenMenu(true);
    props = getProps();
    expect(component).toMatchSnapshot();
    expect(props.children.props.activeTab).toBeNull();
    props.children.props.handleTabClick(item);
    props = getProps();
    expect(props.children.props.activeTab).toBeDefined();
    expect(props.children.props.isSecond).toBeTruthy();
    expect(component).toMatchSnapshot();
  });
  it('Should apply correct styles for small & hidden mode', () => {
    const getProps = () => findByTestAttr(component, 'Sidebar').props();
    let props = getProps();
    props.children.props.setIsSmallMenu(true);
    props.children.props.setIsHiddenMenu(true);
    props = getProps();
    expect(component).toMatchSnapshot();
  });

The question is what should I do to cover this lines addicted to props in styled-components "Wrapper" component?

I've got only 1 passed test addicted to snapshots:

  it('Should apply correct styles', () => {
    const tree = create(
      <ThemeProvider theme={colorsTheme}>
        <Sidebar {...initialState} />
      </ThemeProvider>,
    ).toJSON();
    expect(tree).toMatchSnapshot();
  });

But I don't know how to change states using createShallow.

Aucun commentaire:

Enregistrer un commentaire