Cannot mock in Jest with ES modules

Viewed 154

I'm trying to reproduce the example given in Jest documentation about mocking module. The code is the following one.

users.js

import axios from 'axios'

class Users {
  static all () {
    return axios.get('/users.json').then(resp => resp.data)
  }
}

export default Users

test.js

import axios from 'axios'
import Users from './users'
import { jest } from '@jest/globals'
jest.mock('axios')

test('should fetch users', () => {
  const users = [ { name: 'Bob' } ]
  const resp = { data: users }
  axios.get.mockResolvedValue(resp)

  // or you could use the following depending on your use case:
  // axios.get.mockImplementation(() => Promise.resolve(resp))

  return Users.all().then(data => expect(data).toEqual(users))
})

The code from test.js is a little bit different from the documentation. I had to add import { jest } from '@jest/globals' because of this issue

package.json

{
  ...
  "type": "module",
  "engines": {
    "node": ">=14.17.6"
  },
  "config": {
    "nuxt": {
      "host": "0.0.0.0",
      "port": "8081"
    }
  },
  "scripts": {
    "dev": "cross-env NODE_ENV=development nodemon --insecure-http-parser --inspect server/index.js --watch server",
    "test-server": "cross-env CYPRESS_MODE=true THIRD_PARTY_ROUTES_ENABLED=false npm run start",
    "ci-test-server": "npm run test-server & wait-on http://localhost:8081/fr-FR",
    "build-for-cypress": "cross-env NUXT_ENV_CYPRESS_MODE=true npm run build",
    "build": "nuxt build",
    "start": "cross-env NODE_ENV=production node --insecure-http-parser server/index.js",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint",
    "phrase": "node scripts/phraseapp/phraseapp.js",
    "cypress:open-mocked": "cypress open --env env=mock",
    "cypress:run-mocked": "cypress run --env env=mock",
    "cypress:open-unmocked": "cypress open --env=real,\"TAGS=not @mockOnly\"",
    "cypress:run-unmocked": "cypress run --env=real,\"TAGS=not @mockOnly\"",
    "ci-test": "cross-env TEST_MODE=true jest tests --runInBand  --coverage",
    "front-unit-tests": "cross-env jest tests/client/unit",
    "back-tests": "cross-env TEST_MODE=true jest tests/server --runInBand"
  },
  "dependencies": {
    "@cospired/i18n-iso-languages": "^3.1.0",
    "@jest/globals": "^27.2.5",
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/i18n": "^7.0.3",
    "@nuxtjs/proxy": "^2.1.0",
    "@nuxtjs/style-resources": "^1.2.1",
    "@nuxtjs/toast": "^3.3.1",
    "@sport-activities/nuxt-di": "^0.1.2",
    "@vtmn/css": "^0.22.1",
    "@vtmn/icons": "^0.4.0",
    "abort-controller": "^3.0.0",
    "agentkeepalive": "^4.1.4",
    "atob": "^2.1.2",
    "axios": "^0.22.0",
    "body-parser": "^1.19.0",
    "cacheable-lookup": "^6.0.1",
    "connect-redis": "^6.0.0",
    "cookie-parser": "^1.4.5",
    "cookie-universal-nuxt": "^2.1.5",
    "cross-env": "^7.0.3",
    "csurf": "^1.11.0",
    "dd-trace": "^1.4.1",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "express-session": "^1.17.2",
    "express-validator": "^6.12.2",
    "google-libphonenumber": "^3.2.24",
    "helmet": "^4.6.0",
    "ioredis": "^4.27.9",
    "lodash": "^4.17.21",
    "luxon": "^2.0.2",
    "memory-cache": "^0.2.0",
    "moment": "^2.29.1",
    "morgan": "^1.10.0",
    "nock": "^13.1.3",
    "node-cron": "^3.0.0",
    "node-fetch": "^2.6.1",
    "nuxt": "^2.15.8",
    "nuxt-lazy-load": "^1.2.7",
    "nuxt-purgecss": "^1.0.0",
    "oauth": "^0.9.15",
    "p-limit": "^3.1.0",
    "passport": "^0.4.1",
    "passport-oauth2": "^1.6.1",
    "redlock": "^4.2.0",
    "uuid": "^8.3.2",
    "validator": "^13.6.0",
    "vue-server-renderer": "^2.6.14",
    "vue-toasted": "^1.1.28",
    "wait-on": "^6.0.0",
    "winston": "^3.3.3",
    "world-countries": "^4.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.15.5",
    "@babel/eslint-parser": "^7.15.7",
    "@babel/preset-env": "^7.15.6",
    "@jest/types": "^27.2.4",
    "@types/jest": "^27.0.2",
    "@vue/test-utils": "1.2.2",
    "axios-mock-adapter": "^1.20.0",
    "babel-core": "^7.0.0-bridge.0",
    "css-loader": "^5.2.7",
    "cypress": "8.5.0",
    "cypress-cucumber-preprocessor": "^4.2.0",
    "eslint": "^7.32.0",
    "eslint-config-standard": "^16.0.3",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.24.2",
    "eslint-plugin-jest": "^24.5.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^5.1.0",
    "eslint-plugin-standard": "^5.0.0",
    "eslint-plugin-vue": "^7.18.0",
    "file-loader": "^6.2.0",
    "ioredis-mock": "^5.6.0",
    "jest": "^27.2.4",
    "less": "^4.1.1",
    "less-loader": "^7.2.1",
    "nodemon": "^2.0.13",
    "supertest": "^6.1.6",
    "vue-i18n": "8.26.5",
    "vue-jest": "^3.0.7",
    "vue-svg-loader": "^0.16.0"
  },
  "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": false,
    "step_definitions": "tests/client/e2e/integration/steps",
    "cucumberJson": {
      "generate": true,
      "outputFolder": "tests/client/e2e/integration/cucumber-json",
      "filePrefix": "",
      "fileSuffix": ".cucumber"
    }
  }
}

jest.config.js

export default {
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/tests/client/unit/__mocks__/fileMock.js',
    '\\.(css|less)$': '<rootDir>/tests/client/unit/__mocks__/styleMock.js',
    '^@/(.*)$': '<rootDir>/$1'
  },
  moduleFileExtensions: [
    'js',
    'json',
    'vue',
    'svg'
  ],
  transform: {},
  testMatch: [
    '**/?(*.)+(test).[jt]s?(x)',
    '**/tests/routes/**/*.spec.js'
  ],
  testEnvironment : 'jsdom',
  setupFilesAfterEnv: [
    './tests/jest-setup/jest.setup.ioredis-mock.js',
    './tests/jest-setup/jest.setup.timers.js',
    './tests/jest-setup/jest.setup.envvar.js',
    './tests/jest-setup/jest.setup.nock.js',
    './tests/jest-setup/jest.setup.redis-cache.js'
  ]
}

.babelrc

{
  "presets": ["@babel/preset-env"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ]
}

When executing the test, I'm getting this as a result:

axios.get.mockResolvedValue is not a function
TypeError: axios.get.mockResolvedValue is not a function

Looks like the mock won't work. What have I missed to make it work?

0 Answers
Related