0

I'm learning to test my JavaScript with Jest. I have a basic project that's setup like this:

/
  /src
    myClass.js
  /tests
    myClass.test.js
  package.json

The code looks like this:

myClass.js

export class MyClass {
  constructor() {
    this.result = null;
  }

  calculate() {
    this.result = 1;
    return this.result;
  }
}

myClass.test.js

import { MyClass } from '../src/myClass';

test('Calculate', () => {
  let myObject = new MyClass();
  let result = myObject.calculate();
  expect(result).toBe(1);
});

package.json

{
    "name": "sample-project",
    "version": "0.0.1",
    "type":"module",
    "scripts": {
        "dev": "vite",
        "build": "vite build",
        "serve": "vite preview",
        "test": "jest"
    },
    "dependencies": {
        "vue": "^3.2.16",
        "vue-router": "^4.0.11"
    },
    "devDependencies": {
        "@vitejs/plugin-vue": "^1.9.3",
        "jest": "^27.3.1",
        "vite": "^2.6.4",
        "vite-plugin-html": "^2.1.1",
        "vite-plugin-singlefile": "^0.5.1"
    }
}

When I run my tests using npm run test, which just executes jest, I receive an error that says: SyntaxError: Cannot use import statement outside a module.

What am I doing wrong? How do I test MyClass from Jest?

Dev
  • 921
  • 4
  • 14
  • 31
  • [Is your project set up as `"type": "module"`](https://stackoverflow.com/a/64655153)? – VLAZ Oct 19 '21 at 16:29
  • Does this answer your question? [How to resolve "Cannot use import statement outside a module" in jest](https://stackoverflow.com/questions/58613492/how-to-resolve-cannot-use-import-statement-outside-a-module-in-jest) – BadPiggie Oct 19 '21 at 16:29
  • Shouldn't that be `../src/MyClass` anyway? – jonrsharpe Oct 19 '21 at 16:34
  • @jonrsharpe you are correct. I miscopied it over. The reference is correct. I will update the question. – Dev Oct 19 '21 at 16:39
  • @VLAZ My project is setup as "type":"module" – Dev Oct 19 '21 at 16:40
  • Can you post your `package.json` file, too? – VLAZ Oct 19 '21 at 16:42
  • @BadPiggie unfortunately, no. I'm not using TypeScript, Babel, or Webpack. I'm using good ol' fashioned JavaScript. – Dev Oct 19 '21 at 16:43
  • @VLAZ I just added the `package.json` code. – Dev Oct 19 '21 at 17:00
  • 1
    OK I reproduced this locally. Which is your version of Node.js? – VLAZ Oct 19 '21 at 17:12
  • @VLAZ I have v12.18.2 of Node running locally. – Dev Oct 19 '21 at 17:19
  • Ooh, I don't think that would work. Node [started supporting modules in 13.2.0](https://nodejs.medium.com/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663) as an experimental feature. 14.0.0 was the first LTS with module support. You might need to update your Node installation or use babel or something to use this with 12.18.2, I think. – VLAZ Oct 19 '21 at 17:24
  • @VLAZ I just updated my Node.js installation to version v14.18.1. I also deleted my `node_modules` and `package-lock.json` file. I then ran `npm install`. When I tried to run my test via Jest, via `npm run test`, I still experienced the same issue. – Dev Oct 19 '21 at 17:36
  • 1
    Ugh, so turns out that Jest itself also doesn't fully support modules. I'm trying to wrangle it to work with minimal effort. EDIT: I did get it to work in 14.1.0 with `NODE_OPTIONS=--experimental-vm-modules npx jest` but it's a bit ugly. Supposedly there is a better way to do this. – VLAZ Oct 19 '21 at 17:36

1 Answers1

2

Please follow the Babel sections in the Jest's Getting Started Guide

Simply run:

yarn add --dev babel-jest @babel/core @babel/preset-env

and create a babel.config.js file in the project root directory with the following content:

// babel.config.js
module.exports = {
  presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};

FYI: Jest is using virtual Node environments under the hood. If I remember correctly the oldest supported Node version is 10. Therefore you need to configure a source code transformer like Babel if you want to use ES6 features. (Source)

Michael Haar
  • 671
  • 6
  • 14
  • 1
    I added `babel.config.js` to the root (i.e. `/`) directory of my project. When I run `npm run test`, I receive an error that says: `babel.config.js: Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously.` – Dev Oct 20 '21 at 17:56
  • I think this could be caused by your Node version!? Please see: https://stackoverflow.com/questions/61146112/error-while-loading-config-you-appear-to-be-using-a-native-ecmascript-module-c – Michael Haar Oct 20 '21 at 18:07
  • Maybe renaming it to `babel.config.cjs` works!? – Michael Haar Oct 20 '21 at 18:09
  • 1
    that worked! Thanks! – Dev Oct 20 '21 at 18:17