我有两个带有样式化组件的组件,一个父级和一个子级。父组件将一些道具传递给孩子。我可以根据需要添加样式,但是我认为它们与我的问题无关。
父母
export const NavigationWrapper = ({ ariaLabel, expanded }) => {
const [active, setActive] = React.useState(null);
return (
<NavWrapper
aria-label={ariaLabel}
data-testid="nav-wrapper"
expanded={expanded}
>
<HeaderNavTab expanded={expanded} data-testid="header-nav-tab" href="/">
</HeaderNavTab>
<NavBodyTab
text="Dashboard"
Icon={Grid}
expanded={expanded}
active={active}
setActive={setActive}
/>
<NavBodyTab
text="People"
Icon={People}
expanded={expanded}
active={active}
setActive={setActive}
subNavMenu={[
{ name: "Link1" },
{ name: "Link2", subnav: ["sub link 1", "sub link 2"] },
]}
/>
<NavBottomSpace data-testid="bottom-space" expanded={expanded} />
</NavWrapper>
);
};
子组件从父组件获取道具,并且也具有自己的钩子状态。
孩子
export const NavBodyTab = ({
expanded,
text,
Icon,
subNavMenu,
active,
setActive,
}) => {
const [hovered, setHovered] = React.useState(false);
const [opened, setOpened] = React.useState(null);
const [subNavActive, setSubNavActive] = React.useState(null);
const [subNavOpen, setSubNavOpen] = React.useState(false);
const [subNavHovered, setSubNavHovered] = React.useState(false);
const setActiveTab = (text) => {
if (active === text) {
setActive(null);
} else {
setActive(text);
}
};
const setOpenTab = (text) => {
if (opened === text) {
setOpened(null);
} else {
setOpened(text);
}
};
return (
<div>
<NavTab
expanded={expanded}
opened={opened}
hovered={hovered}
active={active}
text={text}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
onFocus={() => {
setActiveTab(text);
}}
onBlur={() => {
setActiveFunction(subNavMenu);
}}
onClick={() => setOpenTab(text)}
onKeyDown={handleKeyPress}
data-testid={text + "-nav-tab"}
tabIndex="0"
>
{expanded || (hovered && active === null) || active === text ? (
<div>
<IconHolder
expanded={expanded}
hovered={hovered}
text={text}
active={active}
data-testid={text + "-icon-holder"}
>
<Icon
fill={
hovered || active === text ? `${basic[100]}` : `${basic[500]}`
}
stroke={
hovered || active === text ? `${basic[100]}` : `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
</IconHolder>
{text}
{expanded || subNavMenu ? (
<ArrowHolder data-testid={text + "-arrow-holder"}>
{opened === text && subNavMenu && expanded ? (
<ArrowDownward
data-testid={text + "-arrow-icon-down"}
fill={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
stroke={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
) : (
<ArrowForward
data-testid={text + "-arrow-icon"}
fill={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
stroke={
hovered || active === text
? `${basic[100]}`
: `${basic[500]}`
}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
)}
</ArrowHolder>
) : null}
</div>
) : (
<div>
<IconHolder>
<Icon
fill={`${basic[500]}`}
stroke={`${basic[500]}`}
strokeWidth={"2"}
height={"1.5rem"}
width={"1.5rem"}
/>
</IconHolder>
</div>
)}
</NavTab>
</div>
);
};
我在这里切了很多绒毛,但这是基本的想法。现在,我正在尝试进行一项测试,以检查navTab样式是否正确更新。
我在navTab上有一些样式:
const NavTab = styled.div`
height: 3.5rem;
${(props) =>
props.hovered && props.active === null
? `width: 16.25rem; color: ${basic[100]};`
: null}
${(props) =>
props.active === props.text
? `width: 16.25rem; background-color: #434e59; color: ${basic[100]}; outline: none;`
: null}
`;
当用户将鼠标悬停在NavTab上时,我应该能够测试样式是否更改。
test("mouse over", () => {
const expanded = false;
const setExpanded = jest.fn();
React.useState = jest.fn(() => [expanded, setExpanded]);
const { getByTestId, queryByTestId, debug } = render(
<NavigationWrapper
ariaLabel="navigation wrapper"
expanded={false}
/>
);
const navTab = getByTestId("People-nav-tab");
expect(navTab).toHaveStyleRule("width", "5rem");
fireEvent.mouseEnter(navTab);
expect(navTab).toHaveStyleRule("width", "16.25rem");
});
最后一次测试失败。我尝试使用debug()
来查看navTab组件如何随着悬停而变化,并且没有变化。我也使用debug来查看navTab如何在没有焦点的情况下发生变化。我还尝试过fireEvent
单击navTab,再次没有更改调试器的输出。
我真的不知道该如何测试这些样式和状态更改。