Как исправить ошибку типа: navigation.setOptions не является функцией

#javascript #typescript #react-native #jestjs #react-native-testing-library

Вопрос:

Я пытаюсь внедрить в свое приложение библиотеку тестов react native с помощью jest.

На данный момент у меня проблема с навигацией по моему компоненту.

Когда я запускаю тест, у меня появляется ошибка :

 TypeError: navigation.setOptions is not a function
 

Вот мой компонент:

 const initialState: StateTypes = {
  toShowAsGridLayout: false,
  isLoadingMoreContacts: false
};

export const Main: FC<Props> = ({ navigation }) => {
  const dispatch = useDispatch();
  const { data } = useSelector((state: RootState) => state.appReducer);

  const [state, setState] = useState<StateTypes>(initialState);

  useLayoutEffect(() => {
    navigation.setOptions({
      title: state.isLoadingMoreContacts ? strings.LOADING : strings.ALL_CONTACTS   ' - '   data.length,
      headerRight: () => (
        <TouchableOpacity style={styles.changeLayoutButton} onPress={changeLayout}>
          <Text style={styles.changeLayoutText}>{state.toShowAsGridLayout ? strings.LIST : strings.GRID}</Text>
        </TouchableOpacity>
      )
    });
  }, [state.isLoadingMoreContacts, state.toShowAsGridLayout])

  return (
    <View style={styles.container}>
      {renderLayout()}
    </View>
  );
};
 

Вот маршрутизатор:

 const SplashStack = createStackNavigator();
const MainStack = createStackNavigator();

export const RootNavigator = () => {
  const { isDataLoading } = useSelector((state: RootState) => state.appReducer);

  return (
    isDataLoading
      ? <SplashStack.Navigator>
        <SplashStack.Screen name={'SplashStack'} component={Splash} />
      </SplashStack.Navigator>
      : <MainStack.Navigator>
        <MainStack.Screen name={'Main'} component={Main} />
        <MainStack.Screen name={'ContactDetails'} component={ContactDetails} />
      </MainStack.Navigator>
  );
};
 

И само испытание:

 import React from 'react';

import { render } from '@testing-library/react-native';
import { Main } from '../Main';
import * as redux from 'react-redux';
import strings from '../../constants/strings';
import mocks from '../../mocks';

describe('dispatch mock', () => {
  it('should dispatch mock', () => {
    const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
    const useSelectorSpy = jest.spyOn(redux, 'useSelector');
    const mockDispatchFn = jest.fn();
    useDispatchSpy.mockReturnValue(mockDispatchFn);
    useSelectorSpy.mockReturnValue({ data: mocks });

    const { getByText } = render(<Main navigation={({})} />);
    getByText(strings.ALL_CONTACTS);
  });
});
 

Как я могу исправить эту ошибку ? Что я должен передать навигационным реквизитам в строке :

 const { getByText } = render(<Main navigation={({})} />);
 

Ответ №1:

Вам нужно передать объект с setOptions помощью метода.

 const { getByText } = render(<Main navigation={
  {
    setOptions: (props: { title: string, headerRight: React.FC }) => void
  }
} />);