0

我是 React Native 和 Typescript 的新手。我一直在用 Stack Navigation 和 Drawer Navigation 实现一个小项目。该项目一直运行良好,但现在我必须进行一些单元测试。我从一个非常简单的开始,但失败了:/

这是应用程序导航的代码:

导航器.tsx

import App from "../../App";
import React from 'react';
import { Image, StyleSheet, TouchableHighlight } from 'react-native';
import { createAppContainer, NavigationScreenProp, NavigationState, NavigationParams } from 'react-navigation';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { createStackNavigator } from 'react-navigation-stack';
import LoginScreen from "./LoginScreen";
import RegisterScreen from "./RegisterScreen";
import MapScreen from "./MapScreen";
import BikesScreen from "./BikesScreen";
import TheftScreen from "./TheftScreen";
import RentBikeScreen from "./RentBikeScreen";
import RouteListScreen from "./RouteListScreen";
import CouponScreen from "./CouponScreen";
import strings from "../config/strings";

interface Props {
  navigation: NavigationScreenProp<NavigationState,NavigationParams>;
}

interface State {}

export default class NavigatorContainer extends React.Component<Props, State> {  
  render() {

  const DrawerStack = 
  createDrawerNavigator({     
    Map: MapScreen,      
    Bikes: BikesScreen,  
    Theft: TheftScreen,
    RouteList: RouteListScreen,
    Coupon: CouponScreen   
  })


  DrawerStack.navigationOptions = ({ navigation }) => {
    const { routeName } = navigation.state.routes[navigation.state.index];

    const headerTitle = 
    routeName == "Map" ? strings.CONSULT_ROUTE : 
    routeName == "Bikes" ? strings.BIKES_TITLE : 
    routeName == "Theft" ? strings.THEFT_REPORT_TITLE :
    routeName == "Register" ? strings.REGISTER_SCREEN_TITLE :
    routeName == "RouteList" ? strings.ROUTE_LIST_TITLE :
    routeName == "Coupon" ? strings.COUPON_TITLE : "";

    return {
      headerTitle,
      headerLeft: ({ tintColor }: {tintColor: any}) => (
        <TouchableHighlight onPress={() => navigation.toggleDrawer()}><Image
          source={require('../assets/images/drawer.png')}
          style={[styles.icon, { tintColor: tintColor }]}        
        /></TouchableHighlight>)
    };
  };

  const AppNavigator = createStackNavigator(
    {        
      Login: {
        screen: LoginScreen,
        navigationOptions: {
          header: null 
        }      
      },   
      Register: {
        screen: RegisterScreen    
      },      
      DrawerStack: DrawerStack
    },
    {
      initialRouteName: 'Login',
    }
  );

  const AppContainer = createAppContainer(AppNavigator);
    return <AppContainer />;   
  }
}

const styles = StyleSheet.create({
  icon: {
    width: 24,
    height: 24,
  },
});

这是测试:

应用测试.tsx

/**
 * @format
 */
import 'react-native';
import React from 'react';
import App from '../App';

import * as renderer from 'react-test-renderer';

jest.mock('react-native', () => {
  return { 
    StyleSheet: {
      create: () => {

      }
    },
    Platform: {}
  }
});

it('renders correctly', () => {
  renderer.create(<App />);
});

使用“纱线测试”执行测试时,我得到以下信息:

src/screens/Navigator.tsx:50:38 - error TS7031: Binding element 'navigation' implicitly has an 'any' type

所以我用“导航:NavigationScreenProp”更改了“导航”:

DrawerStack.navigationOptions = (navigation : NavigationScreenProp<NavigationState,NavigationParams>) => {....

并且测试通过了!...但是现在当我尝试使用“this.props.navigation.navigate('Map')”进入 DrawerNavigator 的屏幕之一时,例如 MapScreen,我得到了错误:

TypeError: undefined is not an object (evaluating 'navigation.state.routes')

我看到问题出在这一行:

const { routeName } = navigation.state.routes[navigation.state.index];

但我不知道如何解决它,也不明白为什么它只适用于 '({ navigation })'

有任何想法吗?

4

1 回答 1

0

这是一个sintax问题,我改变了这个:

DrawerStack.navigationOptions = ({ navigation }) => {

有了这个:

DrawerStack.navigationOptions = ({navigation} : { navigation : NavigationScreenProp<NavigationState,NavigationParams>}) => {
于 2019-11-26T03:24:52.567 回答