3

I'm developing in React Native and trying to set up jest testing by following the directions at https://airbnb.io/enzyme/docs/guides/react-native.html.

I think I've set everything up correctly. Here's my config:

//setup-tests.js

import "react-native";
import "jest-enzyme";
import Adapter from "enzyme-adapter-react-16";
import Enzyme from "enzyme";

 // Set up DOM in node.js environment for Enzyme to mount to
const { JSDOM } = require("jsdom");

const jsdom = new JSDOM("<!doctype html><html><body></body></html>");
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target)
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: "node.js"
};
copyProps(window, global);

// Set up Enzyme to mount to DOM, simulate events, and inspect the DOM in tests.
Enzyme.configure({ adapter: new Adapter() });

/* Ignore some expected warnings
 * see: https://jestjs.io/docs/en/tutorial-react.html#snapshot-testing-with-mocks-enzyme-and-react-16
 * see https://github.com/Root-App/react-native-mock-render/issues/6
 */
const originalConsoleError = console.error;
console.error = message => {
  if (message.startsWith("Warning:")) {
    return;
  }

  originalConsoleError(message);
};

// jest.config.js

module.exports = {
  setupFilesAfterEnv: "<rootDir>setup-tests.js"
};

// Test.test.js

import React from "react";
import renderer from "react-test-renderer";
import { mount, ReactWrapper } from "enzyme";
import { Provider } from "react-redux";
import { Text } from "react-native";

import LoginView from '../js/LoginView'

You'll see the top of LoginView in a moment.

You'll notice that I haven't even written any tests in the test file, I'm just trying to get jest running to the point where it can evaluate a test.

Without the import LoginView, jest runs and "fails" because my test suite must contain at least one test. Sounds good.

Adding in the import LoginView, I get this error (which shows the import statements at the top of LoginView:

    import Button from './buttons/Button';
           ^^^^^^

    SyntaxError: Unexpected identifier

      1 | import React, { Component } from "react";
    > 2 | import { Input, Button, Image } from "react-native-elements";
        | ^
      3 | import { Text, View } from "react-native";
      4 | import { connect } from "react-redux";
      5 | import F8StyleSheet from "./F8StyleSheet";

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
      at Object.<anonymous> (js/LoginView.js:2:1)

So this doesn't make sense to me for a number of reasons.

  1. LoginView renders fine in the actual app, with no "Unexpected identifier" crashes or warnings or anything
  2. The lower arrows in the error on line 2 point to import, which of course shouldn't be unexpected.
  3. Then there's the upper arrows that indicate a line from react-native-elements, so, I don't know about that.

Now, it does occur to me that the jest.config.js file did require me to use module.exports, and fails/crashes when I tried using export default { setupFiles } (or however I tried to do it, allowing VS Code to update it to ES6 syntax). So maybe that's why it's not liking import.

Even if that's the case, I don't know what the heck to do next.

Update

I put in the code suggested in Brian's answer, and I'm now getting all new errors. Even though the errors suggest fixes, it doesn't seem to help –- I've added the following to my package.json under jest. I'm not sure where Dimensions.js is anyway; plus, I would assume that all this setup I'm doing for React Native in particular would know how to identify the convention of having file.ios.js and file.android.js be equivalent to file.

Here's my "fix" following the instructions, which doesn't help at all.

 "moduleFileExtensions": [
      "js",
      "json",
      "jsx",
      "ts",
      "tsx",
      "node",
      "ios.js",
      "android.js"
    ]

And here's the new errors.

 FAIL  tests/Test.test.js
  ● Test suite failed to run

    Cannot find module './Platform' from 'Dimensions.js'

    However, Jest was able to find:
        './Platform.android.js'
        './Platform.ios.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

    However, Jest was able to find:
        '../Utilities/Dimensions.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

    However, Jest was able to find:
        'buttons/Button.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

    However, Jest was able to find:
        '../js/LoginView.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:229:17)
      at Object.require (node_modules/react-native/Libraries/Utilities/Dimensions.js:14:18)
Jonathan Tuzman
  • 11,568
  • 18
  • 69
  • 129
  • I am having a similar issue, reported [here](https://stackoverflow.com/questions/55807239/react-ga-redux-v7-incompatibility-issue-with-jest), did you managed to solve you issue or are you still stuck ? It could be a compatibility issue with some other packages... – AKFourSeven Apr 23 '19 at 10:22

1 Answers1

2

react-native-elements contains ES6 code.

ES6 code needs to be compiled before it can be run by Jest.

By default Jest doesn't compile anything in node_modules, but react-native has a jest-preset that tells Jest to compile react-native and @react-native-community modules.

To include react-native-elements you will need to tell Jest to compile it as well by adding the following to your Jest config:

transformIgnorePatterns: [
  'node_modules/(?!(jest-)?react-native|@react-native-community|react-native-elements)',
]
Brian Adams
  • 43,011
  • 9
  • 113
  • 111