如何在 react-navigation 5.0 中模拟 useNavigation 钩子以进行玩笑测试?

Ren*_*tia 9 jestjs react-navigation react-navigation-stack react-navigation-v5

我想模拟在我的功能组件中使用的 useNavigation 钩子。任何解决方法如何使用玩笑来模拟它?

import React from 'react';
import { useNavigation } from '@react-navigation/native';
import { TouchableOpacity } from 'react-native';

const MyComponent = () => {
  const { navigate } = useNavigation();

  const navigateToScreen = () => {
    navigate('myScreen', { param1: 'data1', param2: 'data2' })
  }

  return (<TouchableOpacity onPress={navigateToScreen}>
       Go To Screen
     </TouchableOpacity>)
}
Run Code Online (Sandbox Code Playgroud)

如何测试在导航功能中传递的参数?

jos*_*ira 25

我知道我迟到了,但是我遇到了需要知道导航函数何时被调用的问题。

为此,我通过以下方式模拟了该函数,因此mockedNavigate如果我需要测试该函数是否被实际调用,我可以稍后使用该函数:

const mockedNavigate = jest.fn();

jest.mock('@react-navigation/native', () => {
  return {
    ...jest.requireActual('@react-navigation/native'),
    useNavigation: () => ({
      navigate: mockedNavigate,
    }),
  };
});
Run Code Online (Sandbox Code Playgroud)

这允许我稍后使用它,我会知道我是否可以在我的应用程序中正确导航:

expect(mockedNavigate).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 为了使其工作,我必须在测试文件的根目录中声明它(而不是在“describe”或“it/test”语句中 (3认同)

Tho*_*asW 5

另一个相当晚的解决方案,比之前建议的解决方案要干净一些。

const mockedNavigate = jest.fn();

jest.mock('@react-navigation/native', () => (
  { useNavigation: () => ({ navigate: mockedNavigate }) }));
Run Code Online (Sandbox Code Playgroud)

这不包括导航对象的任何其他功能,但它允许您通过以下方式进行测试:

expect(mockedNavigate).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)

或者如果更适用于您的具体情况,请使用expect.toHaveBeenCalledWith()此处)。


Kie*_*ran 4

jest.mock("@react-navigation/native", () => {
  const actualNav = jest.requireActual("@react-navigation/native")
  return {
    ...actualNav,
    useFocusEffect: () => jest.fn(),
    useNavigation: () => ({
      navigate: jest.fn(),
    }),
  }
})
Run Code Online (Sandbox Code Playgroud)

  • 您可以编辑此内容以包括一些对您正在做的事情的解释以及为什么它是解决问题的好方法吗?这将帮助OP和任何未来的读者不仅了解_做什么_,还了解_为什么_。 (2认同)