I've tried for days many ways to set up @testing-library/react-native
with typescript following a sort of guides but still not able to render a simple component.
Roughly, my stack is react native with typescript and jest with ts-jest and react-native-testing-library. I'm following these guidelines among others:
This is the error I'm getting for the simple test component below:
ReferenceError: React is not defined
Component:
import React from 'react'
import { View, Text } from 'react-native'
const SomeComponent = () => {
return (
<View>
<Text>Hello</Text>
</View>
)
}
export default SomeComponent
Test:
import { render } from '@testing-library/react-native'
import SomeComponent from './SomeComponent'
describe('<SomeComponent>', () => {
it('should render some component', () => {
const { getByText } = render(<SomeComponent />)
expect(getByText(/hello/i)).toBeDefined()
})
})
Follow a bunch of configurations for reference:
Dependencies:
{
"name": "connect",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start",
"debug": "open 'rndebugger://set-debugger-loc?host=localhost&port=8081' && react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios",
"pod": "npx pod-install",
"test": "jest",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
"@airbrake/browser": "^2.1.7",
"@react-navigation/bottom-tabs": "^6.2.0",
"@react-navigation/native": "^6.0.8",
"@react-navigation/native-stack": "^6.5.1",
"@reduxjs/toolkit": "^1.8.0",
"@rneui/base": "^4.0.0-rc.1",
"@rneui/themed": "^4.0.0-rc.1",
"@types/react": "^17",
"@types/react-native-dotenv": "^0.2.0",
"@types/react-redux": "^7.1.23",
"axios": "^0.26.1",
"formik": "^2.2.9",
"http-status": "^1.5.0",
"moment": "^2.29.2",
"react": "17.0.2",
"react-native": "0.67.4",
"react-native-blob-util": "^0.13.8",
"react-native-dotenv": "^3.3.1",
"react-native-dropdownalert": "^4.5.1",
"react-native-error-boundary": "^1.1.12",
"react-native-loading-spinner-overlay": "^2.0.0",
"react-native-safe-area-context": "^4.2.2",
"react-native-screens": "^3.13.1",
"react-native-splash-screen": "^3.3.0",
"react-native-vector-icons": "^9.1.0",
"react-redux": "^7.2.6",
"redux-persist": "^6.0.0",
"redux-persist-filesystem-storage": "^4.0.0",
"use-debounce": "^7.0.1",
"yup": "^0.32.11"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.16.11",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^3.0.1",
"@testing-library/jest-native": "^4.0.4",
"@testing-library/react-native": "^9.1.0",
"@types/jest": "^27.4.1",
"@types/react-native": "^0.66.15",
"@types/react-native-loading-spinner-overlay": "^0.5.3",
"@types/react-test-renderer": "^17.0.1",
"babel-jest": "^27.5.1",
"eslint": "7.32.0",
"jest": "^27.5.1",
"metro-react-native-babel-preset": "^0.70.1",
"react-addons-test-utils": "^15.6.2",
"react-native-typescript-transformer": "^1.2.13",
"react-test-renderer": "18.0.0",
"ts-jest": "^27.1.4",
"typescript": "^4.4.4"
},
"resolutions": {
"@types/react": "^17"
}
}
jest.config.js
const { defaults: tsjPreset } = require('ts-jest/presets')
module.exports = {
...tsjPreset,
preset: 'react-native',
transform: {
...tsjPreset.transform,
'\\.js$': '<rootDir>/node_modules/react-native/jest/preprocessor.js',
},
globals: {
'ts-jest': {
babelConfig: true,
},
},
transformIgnorePatterns: [
'/node_modules/(?!(@rneui|@react-native|react-native|react-native-size-matters|react-native-ratings|redux-persist-filesystem-storage|react-native-blob-util)/)',
],
setupFiles: ['./jest.setup.js'],
cacheDirectory: '.jest/cache',
}
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module:react-native-dotenv',
{
moduleName: 'react-native-dotenv',
},
],
],
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["es2017"], /* Specify library files to be included in the compilation. */
"allowJs": true, /* Allow javascript files to be compiled. */
"jsx": "react-native", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"noEmit": true, /* Do not emit outputs. */
"isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
"strict": true, /* Enable all strict type-checking options. */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"skipLibCheck": false, /* Skip type checking of declaration files. */
"resolveJsonModule": true /* Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. */
},
"exclude": [
"node_modules", "babel.config.js", "metro.config.js", "jest.config.js"
]
}
tsconfig.spec.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}
rn-cli.config.js
module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer')
},
getSourceExts() {
return ['ts', 'tsx']
},
}
There is a similar open question about this setup here Setup for React Native/TypeScript/Testing Library/Jest not working
Thanks!
You need run
npm install @babel/plugin-transform-react-jsx --save-dev
into terminal and add plugin intobabel.config.js