08 March, 2020

Setup jest and write a test in ten minutes or less

Setup unit testing for TypeScript with Jest

  npm i -D jest typescript ts-jest @types/jest serve onchange @types/node @types/jest source-map-support @types/source-map-support

The official docs: https://jestjs.io/docs/en/getting-started

To get info about your install run: js>npx envinfo --preset jest

add config file js>jest.config.js

module.exports = {
  preset: 'ts-jest',
  // The test environment that will be used for testing
  testEnvironment: "node",
  roots: [
      "<rootDir>"
    ],
    "modulePaths": [
      "<rootDir>",
    ],
    "moduleDirectories": [
      "node_modules"
    ],
    testMatch: [
      "**/__tests__/**/*.+(ts|tsx|js)",
      "**/__tests__/**/?(*.)+(spec|test).+(ts|tsx|js)",
      "**/?(*.)+(spec|test).+(ts|tsx|js)"
    ],
    transform: {
      "^.+\\.(ts|tsx)$": "ts-jest",
      "^.+\\.(js|jsx|ts)$": "babel-jest"
    },
    coverageReporters: ['json', 'lcov', 'text', 'clover']

common errors

No tests found, exiting with code 1 the js>roots is where the test files are located. If you get this error then change roots to jest knows where your test files are. For example, Its common to have a directory tests with all your tests and for your code to be in a src directory so your config would look like this:

{
       roots: ["<rootDir>/src/", "<rootDir>/__tests__/"],
}

In you package.json add a test command so you can run your tests with js>npm run test

"scripts": {
    "test": "jest --coverage",
    "test:watch": "jest --coverage --watchAll",
    "view:coverage": "serve coverage/lcov-report",
    "clean": "rm -rf coverage /**/*.js src/**/*.map",
    "tsc": "tsc",
    "build:watch": "onchange '**/*.ts' -- npm run tsc"
},

my tsconfig.js file looks like this

{
     "compilerOptions": {
       "outDir": "./dist/",
       "sourceMap": true, // To generate source maps during compilation
       "noImplicitAny": false,
       "module": "commonjs",
       "target": "es6",
       "jsx": "react",
       "skipLibCheck": true
     }
   }

tests if this exists with a 0 then all is well.

and finally create your first test mytest.test.ts

  expect(1+1).toBe(1);
});

You might find it helpful to have open threes console windows with each running:

  • npm run test:watch This automatically runs all the tests on every file save. Very important to re-test your application on every change, especially with TypeScript, as the purpose of following types through a large application is what TS is good at.
  • npm run build:watch Have tsc running after every save as well. Used for a CICD set to transpile the TS to JS. This is configured by the tsconfig.json file.
  • npm run start This starts the app. Since we added a module called source-map-support, our error messages will reflect our TS line of code.