React native testing with Typescript and Jest

I am trying to start test with react-native/expo and typescript. I have created an app with the expo’s basic typescript template.

To start testing, I followed the expo’s documentation on testing with Jest. I have added jest-expo and react-test-renderer as dev dependencies, and have updated the package.json as per the docs:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    ...
    "test": "jest"
  },
  "dependencies": {
    "expo": "~41.0.1",
    "expo-status-bar": "~1.0.4",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@types/jest": "^26.0.23",
    "@types/react": "~16.9.35",
    "@types/react-native": "~0.63.2",
    "@types/react-test-renderer": "^17.0.1",
    "jest-expo": "^41.0.0",
    "react-test-renderer": "^17.0.2",
    "typescript": "~4.0.0"
  },
  "private": true,
  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
    ]
  }
}

This is the test, App.test.tsx:

import renderer from 'react-test-renderer';
import App from "../App";
import React from "react";

describe('<App />', () => {
    it('has 1 child', () => {
        const tree = renderer.create(<App />).toJSON();
        expect(tree.children.length).toBe(1);
    });
});

In the editor (Webstorm) it is throwing 2 errors:

  • tree Object is possibly 'null'.
  • Property 'children' does not exist on type 'ReactTestRendererJSON | ReactTestRendererJSON[]'. Property 'children' does not exist on type 'ReactTestRendererJSON[]'

And also, when I run the test, it throws a different error for <App />

renderer.create(<App />).toJSON():
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Could you please help me what am I missing here. How to test react native with typescript and jest?

hey @mswtm,

I suspect the issue is that you are importing the App.json and not the App component. Can you try fully specifying import App from "../App.tsx"; and let me know what happens?

Seems like there’s a bug/issue with Expo’s Jest preset, as I found out that there’s an open GitHub issue related with the error.

To fix the issue, I had to add this in my jest configuration of package.json :

"moduleFileExtensions": ["ts", "tsx", "js"]

So, the package.json looks somewhat like this:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    ...
    "test": "jest"
  },
  "dependencies": {
    ..
  },
  "devDependencies": {
    ...
  },
  "private": true,
  "jest": {
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
    ],
    "moduleFileExtensions": ["ts", "tsx", "js"]
  }
}