测试 React Native 应用程序:如何修复:navigation.setOptions 不是函数?

Testing React Native app: How to fix: navigation.setOptions is not a function?

这是测试:


describe('<HomeScreen />', () => {
  it('Renders correctly', () => {

// const setOptions = jest.fn(); // 1
// const setOptions = (navigation: any, route: any) => { } // 2
//   const setOptions = (props: HomeProps) => { } // 3
//  const setOptions = (options: Partial<NativeStackNavigationOptions>) => void // 4

    render(
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <HomeScreen navigation={{ setOptions: setOptions }} route={undefined} />
        </PersistGate>
      </Provider>,
    );
  });
});

我已经尝试了 here and here 给出的解决方案,但它们对我不起作用。

我认为问题在于我使用的是 TypeScript 和 React Navigation v6,因为:

  1. const setOptions = jest.fn(); 我得到:

    Type '{ setOptions: jest.Mock<any, any>; }' is not assignable to type 'NativeStackNavigationProp<RootStackParamList, "Home">'.
    

    NativeStackNavigationProp<RootStackParamList, "Home"> 是我的组件类型。

    是这个:export type HomeProps = NativeStackScreenProps<RootStackParamList, 'Home'>;

    稍后我导入为 HomeProps

  2. const setOptions = (navigation: any, route: any) => { }

    我得到:

    Type '(navigation: any, route: any) => void' is not assignable to type '(options: Partial<NativeStackNavigationOptions>) => void'.
    
  3. const setOptions = (props: HomeProps) => { }

    我得到:

    Type '(props: HomeProps) => void' is not assignable to type '(options: Partial<NativeStackNavigationOptions>) => void'.
    
  4. const setOptions = (options: Partial<NativeStackNavigationOptions>) => void (@captain-yossarian 的建议)

我得到:

Type '{ setOptions: (options: Partial<NativeStackNavigationOptions>) => any; }' is not assignable to type 'NativeStackNavigationProp<RootStackParamList, "Home">'.

我该如何解决这个问题?

考虑这个例子:

import React, { FC, useEffect } from "react";
import { View } from "react-native";
import "react-native";
import { render } from "@testing-library/react-native";
import { NativeStackScreenProps, NativeStackNavigationProp } from "@react-navigation/native-stack";

type RootStackParamList = {
  App: undefined;
};

export type AppProps = NativeStackScreenProps<RootStackParamList, "App">;

const App: FC<AppProps> = ({ navigation }) => {
  useEffect(() => {
    navigation.setOptions({
      headerRight: () => <View>hello</View>,
      gestureEnabled: false
    });
  });

  return <View>Hello</View>;
};

export default App;


const setOptions = (options: NativeStackNavigationProp<RootStackParamList, "App">) =>
  void (
    // 4

    render(
      <App navigation={options} route={{ key: 'hello', name: "App", }} />
    )
  );

Playground

我们需要为 options

使用 NativeStackNavigationProp<RootStackParamList, "App"> 类型

这也有效:

我应该使用导航类型中的 HomeNavigationProp 而不是 HomeProps

export type HomeProps = NativeStackScreenProps<RootStackParamList, 'Home'>;

export type HomeNavigationProp = HomeProps['navigation'];

describe('<HomeScreen />', () => {
  it('Renders correctly', () => {
    const navigation: HomeNavigationProp = null;

const { getByText } = render(
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <HomeScreen navigation={navigation} route={undefined} />
        </PersistGate>
      </Provider>,

getByText("hello");
    )
  });