Jest: requiring image in react-native

Created on 20 Apr 2016  Â·  10Comments  Â·  Source: facebook/jest

Hi,

I've been struggling to make Jest work with my react-native project for some days.
Now that I can finally unit test some components, I'm encountering a new bug when requiring images from path.

Here's my current configuration:

package.json

  "jest": {
    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
    },
    "testPathIgnorePatterns": [
      "/node_modules/"
    ],
    "testFileExtensions": [
      "es6",
      "js"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "es6"
    ],
    "unmockedModulePathPatterns": [
      "react",
      "react-addons-test-utils",
      "react-native-router-flux",
      "promise",
      "source-map",
      "key-mirror",
      "immutable",
      "fetch",
      "redux",
      "redux-thunk",
      "fbjs"
    ],
    "collectCoverage": false,
    "verbose": true
  },
...
"scripts": {
   ...
    "test": "rm -rf ./node_modules/jest-cli/.haste_cache && jest  --no-cache"
  },
  ...
  "devDependencies": {
    "babel-core": "^6.4.5",
    "babel-jest": "^9.0.3",
    "babel-preset-react-native": "^1.5.6",
    "jest-cli": "^0.9.2",
    "react": "^0.14.7",
    "react-addons-test-utils": "^0.14.7",
    "react-shallow-testutils": "^1.0.0",
    "redux-mock-store": "^1.0.2"
  }

.babelrc

{
  "presets": ["react-native"]
}

error

  - SyntaxError: Unexpected token ILLEGAL in file 'src/img/gender_male.png'.

    Make sure your preprocessor is set up correctly and ensure your 'preprocessorIgnorePatterns' configuration is correct: http://facebook.github.io/jest/docs/api.html#config-preprocessorignorepatterns-array-string
    If you are currently setting up Jest or modifying your preprocessor, try `jest --no-cache`.
    Preprocessor: node_modules/babel-jest/src/index.js.
    Make sure your '.babelrc' is set up correctly, for example it should include the 'es2015' preset.
    Jest tried to the execute the following preprocessed code:
    �PNG

IHDR>s��DgAMA��
...
�p�e�㢥�[�-p�������=���S��"J,o�ybIEND�B`�

        at ProfileGender.getImage (src/components/ProfileGender.js:40:8)
        at ProfileGender.getButton (src/components/ProfileGender.js:79:6)
        at eval (src/components/ProfileGender.js:88:15)
        at Array.map (native)

Most helpful comment

I had quickly thrown together a react-native app, where I had stolen legacy ipad assets.

Those assets were named as [email protected] etc, I therefore had to update the moduleNameMapper to support the @ character, as well as gif:

    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[@./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
    }

This may be useful to someone in the future.

All 10 comments

This was fixed in Jest 11.0. Please upgrade! If it doesn't work, I'll happily reopen this issue.

Im Having this issue with jest-cli 12.0.2.
Unit testing a component that renders an image based on a prop:
photoPath() { if (this.props.test) { return { source: require('./img/test.png') }; } }

render() { <Image {...this.photoPath()} /> }

The specific error is this: Error: Line 1: Unexpected token ILLEGAL

@cpojer I don't think this is really fixed... :(
I am on Jest CLI v12.1.1 and I unit test this simple function that provides img paths for my react-native app.
`

function provideImgPath(type) {
  switch (type) {
    case 'hamburgermenu':
      return require('../img/hamburgermenu.png');
      break;
    case 'cancelpicker':
      return require('../img/close_button.png');
      break;
    default:
      console.log('ERROR: Invalid type passed to _provideImgPath.');
      throw new Error('Invalid type passed to _provideImgPath.');
  }
}
module.exports = provideImgPath;

`

I noticed that if path is correct ( case 'hamburgermenu': ) than I see this error:
`

Error: Line 1: Unexpected token ILLEGAL
    at constructError (node_modules/esprima/esprima.js:2406:21)
    at createError (node_modules/esprima/esprima.js:2425:17)
    at unexpectedTokenError (node_modules/esprima/esprima.js:2500:13)
    at throwUnexpectedToken (node_modules/esprima/esprima.js:2504:15)
    at scanPunctuator (node_modules/esprima/esprima.js:842:13)
    at advance (node_modules/esprima/esprima.js:1621:16)
    at lex (node_modules/esprima/esprima.js:1690:78)
    at expect (node_modules/esprima/esprima.js:2520:21)
    at parseFunctionSourceElements (node_modules/esprima/esprima.js:4827:9)
    at parseFunctionExpression (node_modules/esprima/esprima.js:5073:16)

`

But if I purposfully change the require path (path is wrong) then I get:
Error: Cannot find module '../imgx/hamburgermenu.png' from 'provideImgPath.js'

My package.json:

`

{
  "name": "BASalesTracker",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "rm -rf ./node_modules/jest-cli/.haste_cache && jest"
  },
  "jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"testPathIgnorePatterns": [
  "/node_modules/"
],
"moduleNameMapper": {
  "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub"
},
"testFileExtensions": [
  "es6",
  "js"
],
"moduleFileExtensions": [
  "js",
  "json",
  "es6"
],
"unmockedModulePathPatterns": [
  "react",
  "react-addons-test-utils",
  "react-native-router-flux",
  "promise",
  "source-map",
  "key-mirror",
  "immutable",
  "fetch",
  "redux",
  "redux-thunk",
  "fbjs"
],
"collectCoverage": true,
"verbose": true
  },
  "dependencies": {
   "@remobile/react-native-splashscreen": "^1.0.3",
   "babel-polyfill": "^6.9.1",
    "react": "^15.1.0",
    "react-native": "^0.27.2",
    "react-native-navbar": "^1.5.0",
    "react-native-side-menu": "^0.19.0",
    "realm": "^0.13.2"
  },
  "devDependencies": {
    "babel-jest": "^12.1.0",
    "babel-polyfill": "^6.9.1",
    "jest-cli": "^12.1.1",
    "react-addons-test-utils": "^15.1.0"
  }
}

`
What is the proper way of unit testing it? Am I missing some config in package.json, like in moduleNameMapper? Please provide clear to follow instructions.

currently my simple test is this:

`

'use strict';
jest.dontMock('../provideImgPath'); 
const provideImgPath = require('../provideImgPath');

describe('provideImgPath', () => {
  it('should provide path for hamburgermenu.png img', () => {

    const result = provideImgPath('hamburgermenu');
  })
});

`
I know there is no expect statement but the errors show as soon as I call a function for a case that returns

require(<path>)

Thank you in advance for your help!

You don't have the relative regex: "^[./a-zA-Z0-9$_-]+.png$": "RelativeImageStub" that you'll need too.

@cpojer Thank you for the super fast answer! I was messing with RelativeImageStub.js (which I found in node_modules/react-native/Libraries/Image/) but I wasn't able to change it to make it works. This time I guess I did, because my test is passing! Thanks so much!

BTW - I made a copy of this file (copy = MyRelativeImageStub.js), made my changes and placed it in my . From package.json I point to MyRelativeImageStub.js. Is this the best practice or should I have used the default /node_modules/react-native/Libraries/Image/RelativeImageStub.js ?

Thank you for answering.

With the new jest-react-native preset this should work when using jest-react-native@test. We will release a major this week where this will work well for jpg files too.

I had quickly thrown together a react-native app, where I had stolen legacy ipad assets.

Those assets were named as [email protected] etc, I therefore had to update the moduleNameMapper to support the @ character, as well as gif:

    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[@./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
    }

This may be useful to someone in the future.

@AlanFoster's solution fixed my issue after updating to RN 0.50 & React 16 with my snapshots.

Bless you @AlanFoster

@AlanFoster
danke

Was this page helpful?
0 / 5 - 0 ratings