axel
axel

Reputation: 4127

How to resolve `require` aliases built with Webpack, for React Unit tests?

question about React unit tests.

I've a ReactJs project and these is the current setup:

Now, I am installing a Jest environment to write tests both for simple javascript files and also for React components.

Simple javascript unit tests are working properly But the test configuration is not working properly for unit tests of React components.

What is not working is the resolving of some requires that use aliases -defined in Webpack- within React components.

const motionConfig = require(`scssConfig/shared/motions.scss`)

scssConfig is an alias configured in the webpack.config.dev.js but in the Jest environment, when executing jest --config jest.config.json, an error pops out because the required file is not read / found and when I try to access its content, this is the error displayed coming out of the line const durationConfig = motionConfig.duration

TypeError: Cannot read property 'duration' of undefined

So basically it is failing the setup of the React environment, because the React component unit test is not yet run.

this is my jest.config.json

{
  "bail": true,
  "setupFilesAfterEnv": ["<rootDir>/jest.setup.js"],
  "testMatch": [
    "<rootDir>/src/app/**/?(*.)+(spec|test).(js|ts)?(x)"
  ],
  "testPathIgnorePatterns": [
    "<rootDir>/build/",
    "<rootDir>/generated/",
    "<rootDir>/node_modules/",
    "<rootDir>/public/"
  ],
  "snapshotSerializers": ["enzyme-to-json/serializer"],
  "collectCoverageFrom": [
    "src/**/*.{js,jsx,ts,tsx}"
  ],
  "testEnvironment": "node",
  "testURL": "http://localhost",
  "transform": {
    "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
    "^.+\\.(css|scss)$": "<rootDir>/config/jest/cssTransform.js",
    "^(?!.*\\.(js|jsx|ts|tsx|json)$)": "<rootDir>/config/jest/fileTransform.js"
  },
  "transformIgnorePatterns": [
    "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
    "^.+\\.module\\.(css|scss)$"
  ],
  "moduleDirectories": [
    "node_modules",
    "<rootDir>/../library"
  ],
  "moduleNameMapper": {
    "\\.(css|scss)$": "identity-obj-proxy",
    "@company/library/(.*)": "<rootDir>/../library/$1"
  },
  "resolver": null,
  "moduleFileExtensions": [
    "js",
    "jsx",
    "ts",
    "tsx",
    "scss",
    "css"
  ]
}

and this is jest.setup.js

import Adapter from 'enzyme-adapter-react-16'
import { shallow, mount, configure } from 'enzyme'
import { format } from 'util'
import React from 'react'
import dotenv from 'dotenv'
import registerRequireContextHook from 'babel-plugin-require-context-hook/register'

dotenv.config({ path: __dirname + '/../.env' })

registerRequireContextHook()
configure({ adapter: new Adapter() })

let global
global.React = React
global.shallow = shallow
global.mount = mount

class ConsoleError extends Error {}

if (global.console) {
  const throws = jest.fn((message, ...rest) => {
    if (!(message instanceof ConsoleError)) {
      const err = new ConsoleError(format(message, ...rest))
      Error.captureStackTrace(err, throws)
      throw err
    }
  })

  global.console = {
    ...global.console,
    error: throws,
    warn: throws,
    exception: throws
  }
}

and this is .babelrc.js

const commonPlugins = [
  [
    require.resolve('babel-plugin-module-resolver'),
    {
      root: ['./src/app/'],
      alias: {
        'scssConfig': '../path/to/scssConfig',
      }
    }
  ]
]

module.exports = {
  plugins: [...commonPlugins]
}

I think the json configuration is properly done but there is something missing.... what? any tips to make it working properly? thanks a lot

Upvotes: 1

Views: 593

Answers (1)

axel
axel

Reputation: 4127

Fixed it like that

the require got replaced by the import

import motionScss from 'scssConfig/shared/gl-config-motion.scss'

in the jest.config.json I did this update

"\\.(scss)$": "<rootDir>/src/app/mocks/tests/scss.js",
"\\.(css)$": "identity-obj-proxy",

and this is the src/app/mocks/tests/scss.js

module.exports = { global: { '$motion': { duration: {}, ease: {} }}};

Upvotes: 1

Related Questions