3

Jest、Expo、React Navigation でテストのスナップショットを作成しようとしていますが、アプリ全体でフックのみを使用しています。最終的には、これらを Jest がクリックスルーし、スナップショットがすべてをテストする e2e テストにしたいと思いますが、react ナビゲーションをレンダリングすることさえできません。expo loader の後のスナップショットには、常に「null」と表示されます。付属のタブスターターの基本的な例に従いましたexpo initが、モックをセットアップする方法を概説する方法は、私のアプリでは機能しません。私はあらゆる種類のことを試しましたが、何も機能しません。

App.tsx

import { Ionicons } from '@expo/vector-icons';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import * as Font from 'expo-font';
import React, { useState } from 'react';
import { YellowBox } from 'react-native';
import { Provider as PaperProvider } from 'react-native-paper';
import { useScreens } from 'react-native-screens';
import { Provider as RxProvider } from 'reactive-react-redux';
import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import SnackBar from './components/UI/Snackbar';
import { socketMiddleware } from './lib/socketMiddleware';
import SwitchNavigator from './navigation/AppNavigator';
import rootReducer from './reducers/rootReducer';
import { theme } from './Theme';

const middleware = [thunk, socketMiddleware()];
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export const store = createStore<iAppState, any, any, any>(
  rootReducer,
  composeEnhancers(applyMiddleware(...middleware))
);

// Must be called prior to navigation stack rendering
useScreens();

YellowBox.ignoreWarnings(['Require cycle:']);

const App = (props) => {
  const [isLoadingComplete, setLoadingComplete] = useState(false);

  if (!isLoadingComplete && !props.skipLoadingScreen) {
    return (
      <AppLoading
        startAsync={loadResourcesAsync}
        onError={handleLoadingError}
        onFinish={() => handleFinishLoading(setLoadingComplete)}
      />
    );
  } else {
    return (
      <RxProvider store={store}>
        <PaperProvider theme={theme}>
          <SwitchNavigator />
          <SnackBar />
        </PaperProvider>
      </RxProvider>
    );
  }
};

const loadResourcesAsync = async () => {
  await Promise.all([
    Asset.loadAsync([
      //nothing
    ]),
    Font.loadAsync({
      ...Ionicons.font,
      TitilliumText250: require('./assets/fonts/TitilliumText22L-250wt.otf'),
      TitilliumText800: require('./assets/fonts/TitilliumText22L-800wt.otf')
    })
  ]);
};

const handleLoadingError = (error: Error) => {
  console.warn(error);
};

const handleFinishLoading = (setLoadingComplete) => {
  setLoadingComplete(true);
};

export default App;

アプリ.test.tsx:

import React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
import NavigationTestUtils from 'react-navigation/NavigationTestUtils';
import renderer from 'react-test-renderer';
import App from './App';
import { theme } from './Theme';

jest.mock('expo', () => ({
  AppLoading: 'AppLoading'
}));
jest.mock('react-native-screens');
jest.mock('react-native-paper');
jest.mock('redux');
jest.mock('reactive-react-redux');
jest.mock('./navigation/AppNavigator', () => 'SwitchNavigator');

describe('App', () => {
  jest.useFakeTimers();

  beforeEach(() => {
    NavigationTestUtils.resetInternalState();
  });

  // success
  it(`renders the loading screen`, () => {
    const tree = renderer.create(<App />).toJSON();
    expect(tree).toMatchSnapshot();
  });

  // this snapshot is always null
  it(`renders the root without loading screen`, () => {
    const tree = renderer
      .create(
        <PaperProvider theme={theme}>
          <App skipLoadingScreen></App>
        </PaperProvider>
      )
      .toJSON();
    expect(tree).toMatchSnapshot();
  });
});

/navigation/AppNavigator.tsx:

import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import LoginStack from './LoginStack';
import TabStack from './TabStack';

/** The most root navigator which allocates to the others. */
const SwitchNavigator = createAppContainer(
  createSwitchNavigator(
    {
      LoginStack: LoginStack,
      TabStack: TabStack
    },
    {
      initialRouteName: 'LoginStack'
    }
  )
);

export default SwitchNavigator;
4

1 に答える 1