Testing JSX files with Jest

I’ve started a new boilerplate expo project using expo init. I chose the option for the “tabs” managed workflow template. Switched into the directory, and yarn'd. The project loads fine on the phone, without any errors. Also, tests pass using yarn test. It’s all great!

But…

We’ve been using React components for nearly two years at my company, along with Reactstrap, and testing it all with jest, and bringing it all together with Webpack. We have strict style guides and naming conventions, and any javascript file with jsx code in it gets the extension .jsx, while others, like constants files or helper functions, maintain their simple .js extension. It also makes using applications like JetBrains Rider more sane, since it knows which code completion, styling, and syntax coloring libraries to use for each file type.

Switching all of the React component files in the boilerplate code from .js to .jsx creates a strange problem: Jest can’t find any eligible files to test. Also, the entire project fails and won’t show up on the phone with expo start, due to this;

Unable to resolve "../../App" from "node_modules\expo\AppEntry.js"

Adding a metro.config.js file to the project like this solves the latter problem:

module.exports = {
  resolver: {
    sourceExts: ['js', 'json', 'ts', 'tsx', 'jsx']
  }
};

The project builds fine in the bundler, and displays on the phone properly. However, tests still aren’t found. After some digging, it seems the relevant lines that are causing the problem are these, from the jest-expo node module, in jest-preset.json:

  "testMatch": [
    "**/__tests__/**/*.(js|ts|tsx)",
    "**/?(*.)+(spec|test).(js|ts|tsx)"
  ]

Temporarily adding jsx to the list of match patterns finally makes the tests run, but they all fail, with unexpected identifier errors for import statements, as well as not being able to reference components directly in test files.

    SyntaxError: Unexpected identifier

      1 | import 'react-native';
      2 | import React from 'react';
    > 3 | import { MonoText } from '../StyledText';
        | ^

trying to reference <App> in App-test.js:

const tree = renderer.create(<App />).toJSON();

// leads to: 

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Remember: This is the boilerplate “Tabs” setup and all I’ve done is change any of the .js files that have JSX in them to have the .jsx extension instead, and added the metro.config.js sourceExts resolver parameter to include .jsx.

Surely, just getting tests to run can’t be this crazy based on file extension. What am I missing here?

1 Like

I’m also running into this, did you find a solution @jdhorner?

Unfortunately, no. After chatting with the devs in the Expo slack, it seems that the best solution is to just stop using the .jsx file extension.

2 Likes

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.