简体   繁体   中英

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.

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. 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. 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:

//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 .

usually, you want to mock api calls and imported modules like 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

First mock getAuth and now You can have two separate test cases.

first test case-> your mocked getAuth function should return some defined value.This will help you in testing {authStatus === 'Authed' && <>{Children}</> . This will also cover the if (status) { setAuthStatus('Authed') } part.

second test case-> your mocked getAuth function should return some undefined value.This will cover your else{ setAuthStatus('Unauthed') } part

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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