【问题标题】:Jest: Testing React state change in useEffect笑话:在 useEffect 中测试 React 状态变化
【发布时间】:2021-01-06 15:04:40
【问题描述】:

我是 Jest 和 Enzyme 的新手,正在努力编写一个单元测试来检查当某个状态值存在时我的组件是否正确呈现。

下面是我的代码:

//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}</>
       </>
    )
}

在上面的代码中,我想测试 authStatus 为默认值时的 Loading 状态,并且我想编写第二个测试来测试在 authStatus 被 Authed 时传递的子项是否被渲染。我找到了一种模拟实现状态更改的方法,但是该实现仅限于一个useEffect,因为将来可能会有多个useEffects,我不想采用这种方法。有没有更好的方法来测试这种行为?

【问题讨论】:

    标签: reactjs jestjs enzyme react-test-renderer


    【解决方案1】:

    首先,您不能只在useEffect 回调中使用await 关键字,它应该是一个async 函数,它会这样做:

    //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}</>
           </>
        )
    }
    

    然后最好不要测试像 state 这样的实现细节。

    通常,您想模拟 api calls 并导入 modules 就像 getAuth 函数。

    所以我认为你应该模拟 getAuth 函数,然后在你的模拟中返回你想要的值,这样你就可以测试像 loading 这样的不同状态是否会发生

    【讨论】:

    • 感谢您的快速回复。这超出了我的问题范围,但请您指导我如何模拟 getAuth 函数。我是编写 Jest 测试用例的新手,正在努力模拟模块(模块是从第三方库导入的)
    • 添加所有Auth.js 代码和您的测试文件,以便我们了解您的操作方式
    • 抱歉延迟回复。我在沙盒上创建了我的代码的简短版本。请看一下there
    【解决方案2】:

    首先模拟getAuth,现在您可以拥有两个单独的测试用例。

    第一个测试用例-> 你模拟的 getAuth 函数应该返回一些定义的值。这将帮助你测试{authStatus === 'Authed' &amp;&amp; &lt;&gt;{Children}&lt;/&gt;。这也将涵盖if (status) { setAuthStatus('Authed') } 部分。

    第二个测试用例->您的模拟 getAuth 函数应该返回一些未定义的值。这将涵盖您的 else{ setAuthStatus('Unauthed') } 部分

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-21
      • 2021-06-03
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 2020-05-13
      • 2017-11-26
      相关资源
      最近更新 更多