Issue
I'm using jest to write tests in my expo project but there's a problem when I'm trying to test App component and I couldn't figure it out .
all answers would be appreciated .
TypeError: Cannot read properties of null (reading 'match')
1 | import 'react-native-gesture-handler';
> 2 | import { registerRootComponent } from 'expo';
| ^
3 | import React, { useState, useEffect,useCallback } from "react";
4 | import { useFonts } from 'expo-font';
5 | import * as SplashScreen from 'expo-splash-screen';
at getDevServer (node_modules/react-native/Libraries/Core/Devtools/getDevServer.js:31:29)
at Object.<anonymous> (node_modules/expo/src/environment/logging.fx.ts:15:39)
at Object.<anonymous> (node_modules/expo/src/Expo.fx.tsx:3:1)
at Object.<anonymous> (node_modules/expo/src/Expo.ts:1:1)
at Object.<anonymous> (src/App.tsx:2:1)
at Object.<anonymous> (src/__tests__/navigation/App.test.tsx:9:1)
package.json
"dependencies": {
"jest": "^29.2.1",
"jest-expo": "^49.0.0",
"react-test-renderer": "^18.2.0",
"ts-node": "^10.9.1",
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@jest/types": "^29.6.3",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^12.3.0",
"@types/jest": "^29.5.6",
"@types/react": "~18.2.14",
"@types/react-native": "^0.72.2",
"@typescript-eslint/eslint-plugin": "^6.8.0",
"@typescript-eslint/parser": "^6.8.0",
"eslint": "^8.2.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-universe": "^12.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-react": "^7.33.2",
"prettier": "^3.0.3",
"ts-jest": "^29.1.1",
"typescript": "^5.1.3"
},
App.tsx
import 'react-native-gesture-handler';
import { registerRootComponent } from 'expo';
import React, { useState, useEffect,useCallback } from "react";
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { StyleSheet, Text, View,ScrollView,SafeAreaView,PixelRatio } from 'react-native';
import RootDrawerNavigator from './navigation/rootDrawerNavigator/RootDrawerNavigator'
SplashScreen.preventAutoHideAsync();
const App = () => {
const designResolution = {
width: 1528,
height: 750
}
console.log(PixelRatio.getFontScale())
const [fontsLoaded, fontError] = useFonts({
'DMRegular': require('./assets/fonts/DMSans-Regular.ttf'),
'DMMedium': require('./assets/fonts/DMSans-Medium.ttf'),
'DMBold': require('./assets/fonts/DMSans-Bold.ttf'),
'DMLight': require('./assets/fonts/DMSans-ExtraLight.ttf'),
});
const onLayoutRootView = useCallback(async () => {
if (fontsLoaded || fontError) {
await SplashScreen.hideAsync();
}
}, [fontsLoaded, fontError]);
if (!fontsLoaded && !fontError) {
return null;
}
return (
<RootDrawerNavigator />
);
}
registerRootComponent(App);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App
App.test.tsx
import * as React from 'react';
import { screen, render, fireEvent ,waitFor} from '@testing-library/react-native';
import {expect, jest, test} from '@jest/globals';
import '@testing-library/jest-native/';
import { NavigationContainer } from '@react-navigation/native';
import renderer from "react-test-renderer"
import { ClientStoreStack, RootDrawerNavigator } from '../../navigation';
import { DashboardScreen } from '../../screens';
import App from '../../App';
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
describe('render correctly', () => {
it('renders App', () => {
const tree = renderer
.create(<App />).toJSON();
expect(tree).toMatchSnapshot();
});
});
jest.config.ts
import type {Config} from 'jest';
const config: Config = {
verbose: true,
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
],
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.{}",
"!**/coverage/**",
"!**/node_modules/**",
"!**/babel.config.js",
"!**/jest.setup.ts",
"!**/pettierrc.js",
"!**/eslintrc.js"
],
"setupFilesAfterEnv": ["@testing-library/jest-native/extend-expect",
"<rootDir>/src/jest.setup.ts"],
"setupFiles": [
],
};
export default config;
setup.jest.ts //for react navigation
import '@testing-library/jest-native/extend-expect';
import 'react-native-gesture-handler/jestSetup';
import {expect, jest, test} from '@jest/globals';
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
Reanimated.default.call = () => {};
return Reanimated;
});
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
Solution
firstly I thought it related to typescript issues and I tried all tricks and solutions for typescript and I spent hours here ,but actually it hasn't been at all . finally I realized that it's because of registerRootComponent .
expo-jest can't mock "expo" ,so we can split the entry point into index.tsx :
import App from './src/App';
import { registerRootComponent } from 'expo';
registerRootComponent(App);
answer here: https://github.com/expo/expo/issues/13026
and don't forget to change the entry point in package.json
Answered By - mermaid
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.