Reactjs 笑话:测试useffect中的React状态变化

Reactjs 笑话:测试useffect中的React状态变化,reactjs,jestjs,enzyme,react-test-renderer,Reactjs,Jestjs,Enzyme,React Test Renderer,我是Jest和Ezyme的新手,正在努力编写一个单元测试来检查我的组件在存在某个状态值时是否正确呈现 下面是我的代码: //Auth.js export const Auth = ({ children }) => { const [authStatus, setAuthStatus] = useState('waiting') useEffect(()=>{ const status = await getAuth() if (stat

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

下面是我的代码:

//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}</>
       </>
    )
}
//Auth.js
导出常量Auth=({children})=>{
常量[authStatus,setAuthStatus]=useState('waiting')
useffect(()=>{
const status=await getAuth()
如果(状态){
setAuthStatus('Authed')
}
否则{
setAuthStatus('Unauthed')
}
},[])
返回(
{authStatus=='waiting'&&&p>正在加载…

} {authStatus=='Authed'&&{Children} ) }

在上面的代码中,我想在
authStatus
为默认值时测试加载状态,我想编写第二个测试来测试在
authStatus
被授权时是否呈现道具中通过的子项。我找到了一种模拟实现状态更改的方法,但该实现仅限于一个
useffect
,因为将来可能会有多个
useffects
,我不想使用这种方法。有没有更好的方法来测试这种行为?

首先,你不能在
useffects
回调中只使用
wait
关键字,它应该是一个
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}</>
       </>
    )
}
//Auth.js
导出常量Auth=({children})=>{
常量[authStatus,setAuthStatus]=useState('waiting')
异步函数checkAuth(){
const status=await getAuth()
如果(状态){
setAuthStatus('Authed')
}
否则{
setAuthStatus('Unauthed')
}
}
useffect(()=>{
checkAuth();
},[])
返回(
{authStatus=='waiting'&&&p>正在加载…

} {authStatus=='Authed'&&{Children} ) }
最好不要测试实现细节,比如
state

通常,您需要模拟
api调用
并导入
模块
,比如
getAuth
函数


因此,我认为您应该模拟
getAuth
函数,然后在模拟中返回所需的值,这样您就可以测试像
加载
这样的不同网络状态是否会发生。首先,您不能在
useffect
回调中仅使用
wait
关键字,它应该是一个
异步
函数,可以实现这一点我不喜欢这样:

//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}</>
       </>
    )
}
//Auth.js
导出常量Auth=({children})=>{
常量[authStatus,setAuthStatus]=useState('waiting')
异步函数checkAuth(){
const status=await getAuth()
如果(状态){
setAuthStatus('Authed')
}
否则{
setAuthStatus('Unauthed')
}
}
useffect(()=>{
checkAuth();
},[])
返回(
{authStatus=='waiting'&&&p>正在加载…

} {authStatus=='Authed'&&{Children} ) }
最好不要测试实现细节,比如
state

通常,您需要模拟
api调用
并导入
模块
,比如
getAuth
函数


因此,我认为您应该模拟
getAuth
函数,然后在模拟中返回所需的值,这样您就可以测试不同的网络状态,如
加载
,是否会发生

第一次模拟
getAuth
,现在您可以有两个单独的测试用例

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


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

第一个模拟
getAuth
,现在你可以有两个独立的测试用例

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


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

感谢quicks的响应。这超出了我的问题范围,但您能否指导我如何模拟
getAuth
函数。我不擅长编写Jest测试用例,正在努力模拟模块(该模块是从第三方库导入的)添加所有
Auth.js
代码和您的测试文件,这样我们就可以看到您如何处理延迟响应。我已经在sandbox上创建了一个简短版本的代码。请看一看。感谢quicks响应。这超出了我的问题范围,但您能否指导我如何模拟
getAuth
乐趣Action.我不擅长编写Jest测试用例,正在努力模拟该模块(该模块是从第三方库导入的),添加所有
Auth.js
代码和您的测试文件,这样我们就可以看到您如何处理延迟响应。我已经在sandbox上创建了一个简短的代码版本。请看一看。