I am new in the testing world and I have spent days trying to figure out how to unit test a signup screen in React Native (with Expo) using React Testing Library. When i run my script to run the tests npm run test
I get an endless list of warnings in the console. I am using React Hook Forms to make the signup form and NativeBase as a UI framework.
How can I get rid of these warnings? Maybe I need to mock some components? Any guidance on how to test this screen would be helpful. Thank you so much.
Some examples of these warnings are:
console.error
Warning: <Text /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
console.error
Warning: React does not recognize the `accessibilityDescribedBy` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `accessibilitydescribedby` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
console.error
Warning: The tag <RNCSafeAreaProvider> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
Here is my entry point App.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NativeBaseProvider } from 'native-base';
import SignUp from './src/screens/signUp/signUp';
import UploadAvatar from './src/screens/uploadAvatar';
type RootStackParamList = {
signUp: undefined;
uploadAvatar: undefined;
};
const Stack = createNativeStackNavigator<RootStackParamList>();
const App = () => {
return (
<NativeBaseProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName="signUp">
<Stack.Screen
name="signUp"
component={SignUp}
options={{ title: 'Registro' }}
/>
<Stack.Screen
name="uploadAvatar"
component={UploadAvatar}
options={{
animation: 'slide_from_right',
title: 'Foto de perfil'
}}
/>
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
);
}
export default App
Here is my screen testing file (I am just trying to get my first test to work).
import React from "react";
import { SignUp } from "./signUp";
import { NativeBaseProvider } from "native-base";
import { render, screen } from "@testing-library/react";
import user from "@testing-library/user-event"
const inset = {
frame: { x: 0, y: 0, width: 0, height: 0 },
insets: { top: 0, left: 0, right: 0, bottom: 0 },
};
describe("SignUpForm", () => {
const {getByLabelText} = render(<NativeBaseProvider initialWindowMetrics={inset}><SignUp /></NativeBaseProvider>);
describe("With invalid inputs", () => {
it ("fails with invalid first name", () => {
const firstName = getByLabelText("Nombre")
user.type(firstName, "123Diego" )
user.click(screen.getByRole("button"))
})
it ("fails with invalid last name", () => {
expect(0).toBe(1)
})
it ("fails with invalid birthday", () => {
expect(0).toBe(1)
})
it ("fails with invalid email", () => {
expect(0).toBe(1)
})
it ("fails with invalid email confirmation", () => {
expect(0).toBe(1)
})
it ("fails with invalid password", () => {
expect(0).toBe(1)
})
it ("fails with invalid password confirmation", () => {
expect(0).toBe(1)
})
})
it ("makes only one API call successfully with valid inputs", () => {
expect(0).toBe(1)
})
});
My jest.config.js
module.exports = {
testEnvironment: "jsdom",
preset: "jest-expo",
globals: {
"ts-jest": {
tsconfig: {
jsx: "react"
}
}
},
transform: {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
"^.+\\.tsx?$": "ts-jest"
},
testMatch: [
"**/?(*.)+(spec|test).ts?(x)"
],
collectCoverage: false,
collectCoverageFrom: [
"**/*.{ts,tsx}",
"!**/coverage/**",
"!**/node_modules/**",
"!**/babel.config.js",
"!**/jest.setup.js"
],
moduleFileExtensions: [
"js",
"ts",
"tsx"
],
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|@react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|sentry-expo|native-base)"
],
coverageReporters: [
"json-summary",
"text",
"lcov"
],
setupFilesAfterEnv: ["./jest.setup.ts"]
};
And my jest.setup.ts
import "@testing-library/jest-dom"
import { server } from "./src/mocks/server"
import 'react-native-gesture-handler/jestSetup';
beforeAll(() => server.listen({
onUnhandledRequest: "error"
}))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
jest.mock('react-native-reanimated', () => {
const Reanimated = require('react-native-reanimated/mock');
// The mock for `call` immediately calls the callback which is incorrect
// So we override it with a no-op
Reanimated.default.call = () => { };
return Reanimated;
});
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');