React Native Testing Library and React Testing Library are both libraries that provide utilities for testing React components. However, they differ in their scope and implementation.
React Native Testing Library
React *Native* Testing Library a library specifically designed for testing React Native components (mobile). It provides a set of tools for testing React Native components in a way that is similar to how users interact with them in the mobile app. This means that it focuses on the functionality of the components, rather than their implementation details. The library uses a similar API to React Testing Library, but with some differences to account for the unique features of React Native.
React Testing Library
React Testing Library on the other hand, is a library designed for testing React components in a browser environment. It provides a set of tools for testing React components in a way that is similar to how users interact with them in a browser. This means that it also focuses on the functionality of the components, rather than their implementation details.
The Differences
One key difference between the two libraries is that React Native Testing Library includes support for native components like View, Text, Image, etc., while React Testing Library only supports web-based components like div, span, img, etc. This can make things a bit challenging at first when trying to write the tests for your React Native app! One thing I found a bit tricky at first was images, but here is a way that works for me.
Let's Test An Image Component!
Below is an example of a component from a Movie app. This MovieCard component shows on the screen and displays details about a movie, such as an image, the title, genre and the release date.
import React from "react";
import { View, Text, Image } from "react-native";
import styles from "./MovieCard.styles";
type MovieCardProps = {
image: string;
title: string;
genre: string;
release: string;
};
const MovieCard = ({
image,
title,
genre,
release,
}: MovieCardProps) => {
return (
<View style={styles.movieCardContainer}>
<Image
source={{ uri: image }}
style={styles.movieCardImage}
testID="movie-image"
accessibilityRole="image"
/>
<View style={styles.movieInfoContainer}>
<View>
<Text style={styles.movieCardTitle}>{title}</Text>
</View>
<View>
<Text>{genre}</Text>
<Text>{release}</Text>
</View>
</View>
</View>
);
};
export default MovieCard;
What I'm focusing on right now is testing that the Image component shows the movie image as expected. Notice I've added testID and an accessibilityRole properties to the Image component; we're going to use those in the test...
import { render } from "@testing-library/react-native";
import MovieCard from "./MovieCard";
// I've created some mock props, including a real image uri from the internet. These props are passed into the MovieCard component that's rendered below in the test.
const mockMovieCardProps = {
image:
"https://images.unsplash.com/photo-1598899134739-24c46f58b8c0?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2312&q=80",
title: "test movie title",
genre: "test genre",
release: "test release date",
};
describe("<MovieCard />", () => {
it("renders with expected details", () => {
const { getByText, getByTestId, getByRole } = render(
<MovieCard
image={mockMovieCardProps.image}
title={mockMovieCardProps.title}
genre={mockMovieCardProps.genre}
release={mockMovieCardProps.release}
/>,
);
// 1. testing the image exists by checking the testId:
const img = getByTestId("movie-image");
// 2. checking the image has the correct properties by accessing the props:
expect(img.props.accessibilityRole).toEqual("image");
expect(img.props.source.uri).toEqual(mockMovieCardProps.image);
});
});
- The first way we can check that our image has been rendered is by checking that the testID exists.
- Then we can get more specific and check that the image has rendered with the correct properties. The Image data is an object, you can access it's properties like img.props.source.uri - this way we can check that it's rendering the correct image based on the source...useful!
- Also if you've given the component an accessibilityRole property, you can access that in a similar way (img.props.accessibilityRole).
So there are some ways that you can test your Image component in React Native! Let me know if you have any good tips of your own :)