简体   繁体   English

开玩笑:测试 React state 的 useEffect 变化

[英]Jest: Testing React state change in useEffect

I am new at Jest and Enzyme, and am struggling to write a unit test to check if my component renders correctly when a certain state value exists.我是 Jest 和 Enzyme 的新手,并且正在努力编写一个单元测试来检查当某个 state 值存在时我的组件是否正确呈现。

Below is my code:下面是我的代码:

//Auth.js
export const Auth = ({ children }) => {
    const [authStatus, setAuthStatus] = useState('waiting')

    useEffect(()=>{
       const status = await getAuth()
       if (status) {
           setAuthStatus('Authed')
       }
       else{
           setAuthStatus('Unauthed')
       }
    },[])

    return (
       <>
          {authStatus === 'waiting' && <p>Loading...</p>}
          {authStatus === 'Authed' && <>{Children}</>
       </>
    )
}

In the above code, I wanted to test the Loading state when authStatus is default and I wanted to write a second test to test if the Children being passed in props are rendered when authStatus is Authed.在上面的代码中,我想在authStatus为默认值时测试 Loading state,并且我想编写第二个测试来测试在authStatus被验证时是否渲染了传入 props 的子项。 I found a way to mock implement the state change, but that implementation is restricted to only one useEffect , as there may be multiple useEffects in the future, I do not want to go with this approach.我找到了一种模拟实现 state 更改的方法,但是该实现仅限于一个useEffect ,因为将来可能会有多个useEffects ,我不想用这种方法 go 。 Is there any better way to test this behavior?有没有更好的方法来测试这种行为?

first, you can't just use await keyword in useEffect callback, it should be an async function which would do that like this:首先,你不能只在useEffect回调中使用await关键字,它应该是一个async function ,它会这样做:

//Auth.js
export const Auth = ({ children }) => {
    const [authStatus, setAuthStatus] = useState('waiting')

    async function checkAuth(){
       const status = await getAuth()
       if (status) {
           setAuthStatus('Authed')
       }
       else{
           setAuthStatus('Unauthed')
       }
    }

    useEffect(()=>{
       checkAuth();
    },[])

    return (
       <>
          {authStatus === 'waiting' && <p>Loading...</p>}
          {authStatus === 'Authed' && <>{Children}</>
       </>
    )
}

and then it's a best practice not to test implementation details like state .然后最好不要测试像state这样的实现细节。

usually, you want to mock api calls and imported modules like getAuth function.通常,您想模拟api calls和导入的modules ,例如getAuth function。

so I think you should mock the getAuth function and then return your desired value in your mock so you can test if differnet state like loading will happen or not所以我认为你应该模拟getAuth function 然后在你的模拟中返回你想要的值,这样你就可以测试是否会发生类似loading的不同 state

First mock getAuth and now You can have two separate test cases.首先模拟getAuth ,现在您可以有两个单独的测试用例。

first test case-> your mocked getAuth function should return some defined value.This will help you in testing {authStatus === 'Authed' && <>{Children}</> .第一个测试用例->您模拟的 getAuth function 应该返回一些定义的值。这将帮助您测试{authStatus === 'Authed' && <>{Children}</> This will also cover the if (status) { setAuthStatus('Authed') } part.这也将涵盖if (status) { setAuthStatus('Authed') }部分。

second test case-> your mocked getAuth function should return some undefined value.This will cover your else{ setAuthStatus('Unauthed') } part第二个测试用例->您模拟的 getAuth function 应该返回一些未定义的值。这将涵盖您的else{ setAuthStatus('Unauthed') }部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM