Reactjs 测试由Jest中的组件引起的状态更改

Reactjs 测试由Jest中的组件引起的状态更改,reactjs,unit-testing,jestjs,zustand,Reactjs,Unit Testing,Jestjs,Zustand,我对使用jest非常陌生,我正在尝试测试一个组件,该组件可以对我的全局状态进行状态更改(使用Zustand)。基本上,我点击一个按钮,它会向我的state.traits添加一个项目。以下是我的组件代码: import { Flex, useToast } from '@chakra-ui/react' import { FC } from 'react' import { useProfileStore } from 'stores/profileStore' interface DataTr

我对使用jest非常陌生,我正在尝试测试一个组件,该组件可以对我的全局状态进行状态更改(使用Zustand)。基本上,我点击一个按钮,它会向我的state.traits添加一个项目。以下是我的组件代码:

import { Flex, useToast } from '@chakra-ui/react'
import { FC } from 'react'
import { useProfileStore } from 'stores/profileStore'

interface DataTrait {
    name: string,
    id: string
}

type Props = {
    trait: DataTrait
}

export const ChipItem: FC<Props> = ({ trait }) => {
    const { traits, setTraits } = useProfileStore()
    const toast = useToast()
    const traitNames = traits.map((trait) => trait.name)
    const emptyTraits = traits.filter((trait) => trait.name === "")

    const handleClick = (trait: DataTrait) => {
        if (!traitNames.includes(trait.name) && emptyTraits.length !== 0) {
            let currentItem = traits.filter(trait => trait.name === "")[0]
            let items = [...traits]
            let item = {position: currentItem.position, id: trait.id, name: trait.name}
            items[items.indexOf(currentItem)] = item
            setTraits(items)
        
        } else if (emptyTraits.length === 0){
            toast({
                title: 'Error',
                status: 'error',
                description: 'Only 5 traits can be selected',
                isClosable: true,
                duration: 5000
            })
        } else {
            toast({
                title: 'Error',
                status: 'error',
                description: 'Please select unique traits',
                isClosable: true,
                duration: 5000
            })
        }
    }

    return (
        traitNames.includes(trait.name) ? (
            <Flex mx={4} p={2} cursor="pointer" borderRadius="20px" backgroundColor="green" borderWidth="1px" borderColor="white" textColor="white" onClick={() => handleClick(trait)}>{trait.name}</Flex>
        ) : (
            <Flex mx={4} p={2} cursor="pointer" borderRadius="20px" borderWidth="1px" borderColor="grey" onClick={() => handleClick(trait)}>{trait.name}</Flex>
        )
    )
}
从'@chakra ui/react'导入{Flex,useToast}
从“react”导入{FC}
从“stores/profileStore”导入{useProfileStore}
接口数据特征{
名称:string,
id:字符串
}
类型道具={
特征:数据特征
}
导出常量ChipItem:FC=({trait})=>{
const{traits,setTraits}=useProfileStore()
const toast=useToost()
const traitNames=traits.map((trait)=>trait.name)
const emptyTraits=traits.filter((trait)=>trait.name===“”)
常量handleClick=(trait:DataTrait)=>{
如果(!traitNames.includes(trait.name)&&emptyTraits.length!==0){
让currentItem=traits.filter(trait=>trait.name==“”)[0]
让项目=[…特征]
let item={position:currentItem.position,id:trait.id,name:trait.name}
项目[项目.索引(当前项目)]=项目
设置特征(项目)
}else if(emptyTraits.length==0){
吐司({
标题:“错误”,
状态:“错误”,
描述:“只能选择5个特征”,
不公开:是的,
持续时间:5000
})
}否则{
吐司({
标题:“错误”,
状态:“错误”,
描述:“请选择唯一特征”,
不公开:是的,
持续时间:5000
})
}
}
返回(
traitNames.includes(trait.name)(
handleClick(trait)}>{trait.name}
) : (
handleClick(trait)}>{trait.name}
)
)
}
这是我的商店代码:

import create from 'zustand'

export interface Trait {
    position: string,
    name: string,
    id: string,
}

export type Traits = Trait[]

const initialTraits = [
    {position: "0", name: "", id: ""},
    {position: "1", name: "", id: ""},
    {position: "2", name: "", id: ""},
    {position: "3", name: "", id: ""},
    {position: "4", name: "", id: ""},
]

export type ProfileStore = {
    traits: Traits;
    setTraits: (traits: Traits) => void;
    clearTraits: () => void;
}

export const useProfileStore = create<ProfileStore>((set) => ({
    traits: initialTraits,
    setTraits: (traits) => set({ traits }),
    clearTraits: () => set({ traits: initialTraits })
}))

从“zustand”导入创建
导出接口特性{
位置:字符串,
名称:string,
id:string,
}
导出类型Traits=Trait[]
常量initialTraits=[
{位置:“0”,名称:,id:},
{位置:“1”,名称:,id:},
{位置:“2”,名称:,id:},
{位置:“3”,名称:,id:},
{位置:“4”,名称:,id:},
]
导出类型配置文件存储={
性状:性状;
setTraits:(traits:traits)=>void;
clearTraits:()=>void;
}
export const useProfileStore=创建((设置)=>({
特征:初始特征,
setTraits:(traits)=>set({traits}),
clearTraits:()=>set({traits:initialTraits})
}))
这是我的测试代码:

import React from 'react';
import { ChipItem } from "../../ChipList/ChipItem";
import { act, render, renderHook } from "@testing-library/react";
import { useProfileStore } from "../../../stores/profileStore";

const stubbedTrait = {
    name: "Doing Work",
    id: "efepofkwpeok"
}

it("displays the trait chip", () => {
    const { queryByText } = render(<ChipItem trait={stubbedTrait} />);
    expect(queryByText("Doing Work")).toBeTruthy();
})

it("sets the chip information in the store", () => {
    act(() =>  {
        const { traits } = renderHook(() => useProfileStore())
        const { getByText } = render(<ChipItem trait={stubbedTrait}/>);
        getByText(stubbedTrait.name).click()
        expect(traits.includes(stubbedTrait)).toBeTruthy()
    })
})
从“React”导入React;
从“../../ChipList/ChipItem”导入{ChipItem}”;
从“@testing library/react”导入{act,render,renderHook};
从“../../../stores/profileStore”导入{useProfileStore}”;
常数stubbedctrait={
名称:“正在工作”,
id:“efepofkwpeok”
}
它(“显示特征芯片”,()=>{
常量{queryByText}=render();
expect(queryByText(“正在工作”).toBeTruthy();
})
它(“设置存储中的芯片信息”,()=>{
行动(()=>{
const{traits}=renderHook(()=>useProfileStore())
const{getByText}=render();
getByText(stubbedTrait.name)。单击()
expect(traits.includes(stubbedctrait)).toBeTruthy()
})
})
发生的事情是,它一直告诉我renderHook不是一个函数,traits总是没有定义。任何帮助都将不胜感激