无法让 Jest expo 应用程序与 react-navigation 一起使用
Posted
技术标签:
【中文标题】无法让 Jest expo 应用程序与 react-navigation 一起使用【英文标题】:Can't get Jest expo app to work with react-navigation 【发布时间】:2020-03-27 10:00:30 【问题描述】:我正在尝试使用 Jest、Expo、React Navigation 进行快照测试,而我的整个应用程序仅使用钩子。我希望最终将这些变成 e2e 测试,在其中 Jest 单击并快照测试所有内容,但我什至无法获得反应导航来渲染。我在博览会加载器之后的快照总是显示“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;
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;
【问题讨论】:
【参考方案1】:我遇到了类似的问题,并通过以下方式找到了解决方法:https://github.com/expo/expo/issues/7155#issuecomment-592681861
似乎 act() 对我来说神奇地阻止它返回 null(不确定如何)
更新您的测试以像这样使用它:
import act, create from 'react-test-renderer';
it('renders the root without loading screen', () =>
let tree;
act(() =>
tree = create(
<PaperProvider theme=theme>
<App skipLoadingScreen></App>
</PaperProvider>
);
);
expect(tree.toJSON()).toMatchSnapshot();
);
注意:当我更改使用“react-test-renderer”导入的方式时,我的测试无法找到 act() 作为函数,一个简单的 npm 包重新安装解决了这个问题!
【讨论】:
以上是关于无法让 Jest expo 应用程序与 react-navigation 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
react-native-vector-icons/MaterialIcons jest-expo 快照测试错误与打字稿
在未弹出 Redux 的情况下测试 Jest React-Native Expo CRNA
Jest-Expo 在示例上崩溃(React.createElement:类型无效 - 应为字符串)
React Native Expo - Jest - React Native Firebase - Invariant Violation:Native 模块不能为空