React test with jest does not honor moduleNameMapp

2019-06-27 23:35发布

问题:

I am using jest and enzyme to test my react component. I am also using blueprint icons as one of the dependency in my react component. As part of my webpack config, following is added:

config.resolve.alias = {
    blueprintIcons: path.resolve('./node_modules/@blueprintjs/icons'),
    blueprint: path.resolve('./node_modules/@blueprintjs/core')
};

Following is added as part of jest config:

    rootDir: '.',
    roots: [
        '<rootDir>/__test__/'
    ],
    transformIgnorePatterns: [
        '<rootDir>/node_modules/'
    ],
    transform: {
        '^.+\\.jsx?$': 'babel-jest'
    },
    testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$',
    moduleDirectories: ['node_modules'],
    moduleFileExtensions: [
        'js',
        'jsx',
        'json',
        'node'
    ],
    moduleNameMapper: {
        '\\.(css|scss)$': 'identity-obj-proxy',
        blueprintIcons: '<rootDir>/node_modules/@blueprintjs/core'
        blueprint: '<rootDir>/node_modules/@blueprintjs/core'
    },
    snapshotSerializers: ['enzyme-to-json/serializer']
};

Here is my component:

import React, { Component } from 'react';
import Icon from 'blueprint';
import IconNames from 'blueprintIcons';
class Foo extends Component {
  render() {
      return (
        <div>
           <p>Hello Foo</p>
           <Icon icon={IconNames.HOME} iconSize={Icon.SIZE_LARGE}/>
        </div>
      );
  }
}
export default Foo;

Here is my foo.test.js

import React from 'react';
import Foo from '../../src/Components/Foo';
import Adapter from 'enzyme-adapter-react-16';
import Enzyme, { mount, shallow } from 'enzyme';

describe('Reviews component', () => {
    it('render component when loading in progress', () => {
        const mountedComponent = mount(<Foo />);
    });
});

When I am trying to test that component, the test fails with

TypeError: Cannot read property 'HOME' of undefined at IconNames.HOME

Here are some packages specified in my package.json

"babel-cli": "6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.0.1",
"babel-loader": "7.1.4",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.4",
"jest": "^23.1.0",
"jest-html-reporter": "^2.3.0",
"@blueprintjs/core": "^2.3.1",
"react": "16.2.0"

I am using react 16.2.0

I tried mocking it but doesn't work(maybe I am not doing it correctly) but here is the code which I am using:

jest.mock('@blueprintjs/icons', () => (
    { IconNames: {HOME: 'home' }}));

回答1:

I think mocking is a possible solution - Not sure exactly why your code is not working (possibly because it's not within the default key, or the name of the mock is incorrect), but you can try something else.

  1. In your Jest config, add the following:
"setupFiles": [
    "./__mocks__/mockIcons.js"
],
  1. Create /__mocks__ folder in your root folder
  2. Create mockIcons.js inside __mocks__ with the following code:
jest.mock("blueprint", () => ({
    default: {
        Icon: { SIZE_LARGE: 'large' }
    }
}))

jest.mock("blueprintIcons", () => ({
    default: {
        IconNames: { HOME: 'home' }
    }
}))

Try to use @blueprintjs/icons as the mock name if nothing else works.



回答2:

For me, the following solution worked:

In jest config:

moduleNameMapper: {
        '^blueprint': '<rootDir>/node_modules/@blueprintjs/core',
        '^@blueprintjs/(.*)$': '<rootDir>/node_modules/@blueprintjs/$1'
}

Rest everything remained the same.