I have written a component that does two things :
- show a banner: when
netInfo.isConnected
change and isfalse
or whennetInfo.isInternetReachable
change and is stillfalse
after3 seconds
- hide a banner: when
netInfo.isConnected
ornetInfo.isInternetReachable
change totrue
For (1) hiding after 3 seconds is possible by creating a ref that can be readen 3 seconds later.
(2) is pretty straightforward, a simpleuseEffect
can help me to do that, my components looks like this:
export function OfflineModeContainer({ children }: { children: ReactNode }) {
const netInfo = useNetInfo()
const [show, setShow] = useState(!netInfo.isConnected)
const isInternetReachable = useRef(netInfo.isInternetReachable)
useEffect(() => {
setShow(!netInfo.isConnected)
}, [netInfo.isConnected])
useEffect(() => {
isInternetReachable.current = netInfo.isInternetReachable
let timer: number | undefined
if (!isInternetReachable.current) {
timer = setTimeout(() => {
if (!isInternetReachable.current) {
setShow(true)
}
}, 3000)
} else {
setShow(false)
}
return () => {
if (timer) {
clearInterval(timer)
}
}
}, [netInfo.isInternetReachable])
return (
<View>
<View>{children}</View>
{show ? (
<View>
<View>{t`aucune connexion internet.`}</<View>
</<View>
) : null}
</View>
)
}
This works fine. I now want to test both useEffect
using React testing library.
- How can I test the 1st useEffect and 2nd useEffect for the hide feature when one of the value switch to true ? I believe the difficulty here is to trigger the hook after a while during the test
- How can I test the
setTimeout
asynchronous operation? - How to test the
clearTimer
Live demo reproduction
https://codesandbox.io/s/react-native-test-forked-7nc5zc
Unfortunately, I can't use mock in codesandbox due to known open issue with jest.mock
, still open until 2018 https://github.com/codesandbox/codesandbox-client/issues/513
For this reason, I add the testing logs here:
$ TZ=UTC JEST=true jest --forceExit /home/dka/workspace/github.com/pass-culture/pass-culture-app-native/src/libs/network/__tests__/OfflineModeContainer.test.tsx
FAIL src/libs/network/__tests__/OfflineModeContainer.test.tsx (5.178 s)
<OfflineModeContainer />
✓ should render children and show banner when offline at init when isConnected is false (36 ms)
✓ should render children and not show banner when offline at init when isConnected is true (5 ms)
✕ should not show "aucune connexion internet." at init, then show when isConnected is false, then hide when isConnected switch back to true (558 ms)
● <OfflineModeContainer /> › should not show "aucune connexion internet." at init, then show when isConnected is false, then hide when isConnected switch back to true
expect(received).toBeFalsy()
Received: {"_fiber": {"_debugHookTypes": null, "_debugID": 163, "_debugNeedsRemount": false, "_debugOwner": [FiberNode], "_debugSource": null, "actualDuration": 0, "actualStartTime": -1, "alternate": null, "child": [FiberNode], "childLanes": 0, "dependencies": null, "elementType": [Function Component], "firstEffect": null, "flags": 1, "index": 0, "key": null, "lanes": 0, "lastEffect": null, "memoizedProps": [Object], "memoizedState": null, "mode": 0, "nextEffect": null, "pendingProps": [Object], "ref": null, "return": [FiberNode], "selfBaseDuration": 0, "sibling": null, "stateNode": [Component], "tag": 1, "treeBaseDuration": 0, "type": [Function Component], "updateQueue": [Object]}}
50 | </OfflineModeContainer>
51 | )
> 52 | expect(await renderAPI.queryByText('aucune connexion internet.')).toBeFalsy()
| ^
53 | })
54 | })
55 |
1条答案
按热度按时间b1zrtrql1#
我是这样解决这个问题的: