【问题标题】:How to test react navigation authentication flow?如何测试反应导航认证流程?
【发布时间】:2020-06-28 00:34:32
【问题描述】:

我正在开发一个 React Native 应用程序。我正在做类似here 解释的事情来实现身份验证流程。所以,我创建了一个如下所示的AppContainer:

import {createAppContainer, createSwitchNavigator, createStackNavigator} from "react-navigation";
import AuthLoadingScreen from "../screens/auth/auth-loading-screen";

const AppStack = createStackNavigator({ Home: {screen: HomeScreen} });
const AuthStack = createStackNavigator({ SignIn: {screen: SignInScreen} });

const AppContainer = createAppContainer(
  createSwitchNavigator(
    {
      AuthLoading: AuthLoadingScreen,
      App: AppStack,
      Auth: AuthStack,
    },
    {
      initialRouteName: "AuthLoading",
    },
  ),
);

export {AppContainer};
export default AppContainer;

那么,这就是我在App.tsx 中的内容:

import React from "react";
import AppContainer from "./src/navigation/index";

const App = () => {
  return <AppContainer />;
};

export default App;

还有,这是我的App.test.tsx:

import 'react-native';
import React from 'react';
import App from '../App';
import renderer from 'react-test-renderer';

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

这是我的package.json 文件中的jest 配置:

  "jest": {
    "preset": "react-native",
    "setupFiles": [
      "./node_modules/react-native-gesture-handler/jestSetup.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|@react-native-community/*|react-navigation|react-navigation-stack|@react-navigation/.*)"
    ],
    "timers": "fake",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  },

现在,当我运行 yarn test 时,测试通过了,但出现以下错误:

ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.get useTheme [as useTheme] (node_modules/@react-navigation/core/lib/commonjs/index.js:3:18)
      at Object.get [as useTheme] (node_modules/react-navigation/src/index.js:169:19)
      at useTheme (node_modules/react-navigation-stack/lib/commonjs/utils/useTheme.js:65:36)
      at CardContainer (node_modules/react-navigation-stack/lib/commonjs/vendor/views/Stack/CardContainer.tsx:165:5)
      at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5762:18) PASS  __tests__/App-test.tsx (10.657s)   ✓ renders correctly (93ms)

  console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10695
    The above error occurred in the <CardContainer> component:
        in CardContainer (created by CardStack)
        in View (created by View)
        in View (created by MaybeScreen)
        in MaybeScreen (created by CardStack)
        in View (created by View)
        in View (created by MaybeScreenContainer)
        in MaybeScreenContainer (created by CardStack)
        in CardStack (created by KeyboardManager)
        in KeyboardManager (created by Context.Consumer)
        in RNCSafeAreaView (created by RNCSafeAreaView)
        in RNCSafeAreaView (at src/index.tsx:28)
        in SafeAreaProvider (created by Context.Consumer)
        in SafeAreaProviderCompat (created by StackView)
        in View (created by View)
        in View (created by StackView)
        in StackView (created by StackView)
        in StackView
        in Unknown (created by Navigator)
        in Navigator (created by SceneView)
        in SceneView (created by SwitchView)
        in SwitchView (created by Navigator)
        in Navigator (created by NavigationContainer)
        in NavigationContainer (created by App)
        in App

    React will try to recreate this component tree from scratch using the error boundary you provided, NavigationContainer.

  console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10695
    The above error occurred in the <NavigationContainer> component:
        in NavigationContainer (created by App)
        in App

    Consider adding an error boundary to your tree to customize error handling behavior.

我该如何解决这个问题?

【问题讨论】:

    标签: typescript react-native jestjs react-navigation


    【解决方案1】:

    你需要为你的玩笑做一些配置:

    1) 在您的根目录__mocks__ 中创建一个文件夹,然后在其中归档,名称为:react-navigation.js,并将以下代码放入其中:

    export default {
       NavigationActions: () => {}
    };
    

    2) 在你的根目录下创建一个文件名:jest.config.js 并把这些代码放进去:

    module.exports = {
        preset: 'react-native',
        setupFilesAfterEnv: [
          './__mocks__/mockFirebase'
        ],
        automock: false,
        moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
        testPathIgnorePatterns: [
          "node_modules"
        ]
    }
    

    此外,您可以将其他配置添加到此文件中,然后从您的 package.json 文件中删除 jest config

    3) 也可能您需要在__mocks__ 文件夹中添加一些其他文件:

    react-native-gesture-handler.js 文件代码如下:

    export const RectButton = () => 'View';
    export const State = () => 'View';
    export const LongPressGestureHandler = () => 'View';
    export const BorderlessButton = () => 'View';
    export const PanGestureHandler = () => 'View';
    

    还有一些类似的包:react-native-device-info,Firebase,@react-native-community你需要做类似的事情,你可以在这里问或搜索 关于 Google 上的内容。

    【讨论】:

    • 谢谢!我开玩笑的配置中的setupFiles 中的./node_modules/react-native-gesture-handler/jestSetup.js 负责模拟react-native-gesture-handler。我已经解决了这个问题。没有必要模拟react-navigation,至少到目前为止我正在测试。我只需要将快照测试更改为异步测试,因为我的身份验证流程中确实有异步功能。
    【解决方案2】:

    问题是我的身份验证流程中有一些异步功能。因此,我所要做的就是将测试方法更改为异步方法,如下所示:

    import 'react-native';
    import React from 'react';
    import App from '../App';
    import renderer from 'react-test-renderer';
    
    it('renders correctly', async () => {
      renderer.create(<App />);
    });
    

    这解决了问题。

    【讨论】:

      猜你喜欢
      • 2017-02-25
      • 2021-01-20
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      • 2020-06-22
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多