Select Page

TypeScript development is very often connected with UI frameworks like Angular or React or many others.
They come with its own CLI and templates setup making Unit Testing for TypeScript extremely easy. The situation might look a bit different if you don’t use any of those compfortable UI frameworks for whatever reason.

Pure TypeScript Unit Testing

If you develop TypeScript purely and would like to do Unit Testing, the following setup of Jasmine and Babel might be helpful to you, check up the source code here.

Let’s take a closer look on what Jasmine and Babel exactly do.

Jasmine

Jasmine is a popular Unit Testing javascript framework. It consists of Suites, each Suite contains a number of tests. The Suites are normally saved under .spec.js files. This is how a very basic Suite may look like.

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

Jasmine has a lot of great features but it focuses on javascript and not TypeScript unfortunately. This is where Babel helps us.

To setup Jasmine locally you would need to run:

npm init
npm i --save-dev jasmine
npm i @types/jasmine
npx jasmine init

Make sure the Jasmine configuration file ./spec/support/jasmine.json is looking like this.

{
  "spec_dir": "spec/out",
  "spec_files": ["**/*[sS]pec.js"],
  "helpers": ["helpers/**/*.js"],
  "stopSpecOnExpectationFailure": false,
  "random": true
}

Babel

Babel is very powerful compiler that can convert code from different TypeScript versions into javascript or just from modern javascript specification format into an older one to ensure better browser compatibility. For instance ECMAScript 2020 into ECMAScript 2009.

To setup Babel locally you would need to run:

npm i --save-dev @babel/register @babel/core @babel/cli @babel/polyfill
npm i @babel/preset-env @babel/preset-typescript --save-dev

In the root of our project a babel config file should be created.
.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"]
}

Babel & Jasmine

Putting these two packages together lets us write TypeScript code and test a javascript version of it.

Assuming our TypeScript code is stored in the folder ./app, let’s see how it could look like:

typescript-calculator.ts

export class TypescriptCalculator {
  public sum(x: number, y: number): number {
    return x + y;
  }
}

The corresponding Unit Test for it could be as follows:

typescript-calculator.spec.ts

import { TypescriptCalculator } from './typescript-calculator';

describe('TypescriptCalculator', () => {
  it('should sum', () => {
    // arrange
    const calculator = new TypescriptCalculator();
    var x1 = 5;
    var x2 = 10;

    // act
    const sum = calculator.sum(x1, x2);

    // assert
    expect(sum).toEqual(15);
  });
});

We should tell npm how to run the tests, for this purpose a package.json file should be modified, "scripts" section.

"scripts": {
    "test": "babel app --delete-dir-on-start -d \"spec/out\" app --out-dir \"spec/out\" -x \".ts\" -x \".js\" && jasmine"
  },

To run the tests you would just need to enter npm test in your console.

Assuming the test passes this is how the console output looks like:

➜  ts-unit-testing git:(master) ✗ npm test

> ts-unit-testing@1.0.0 test /git/ts-unit-testing
> babel app --delete-dir-on-start -d "spec/out" app --out-dir "spec/out" -x ".ts" -x ".js" && jasmine

Successfully compiled 2 files with Babel (421ms).
Randomized with seed 30961
Started
.


1 spec, 0 failures
Finished in 0.007 seconds
Randomized with seed 30961 (jasmine --random=true --seed=30961)

Let’s now modify the class so sum function does not work as expected.

export class TypescriptCalculator {
  public sum(x: number, y: number): number {
    return x * y;
  }
}

The console output would look like this.

➜  ts-unit-testing git:(master) ✗ npm test

> ts-unit-testing@1.0.0 test /git/ts-unit-testing
> babel app --delete-dir-on-start -d "spec/out" app --out-dir "spec/out" -x ".ts" -x ".js" && jasmine

Successfully compiled 2 files with Babel (395ms).
Randomized with seed 16618
Started
F

Failures:
1) TypescriptCalculator should sum
  Message:
    Expected 50 to equal 15.
  Stack:
    Error: Expected 50 to equal 15.
        at <Jasmine>
        at UserContext.<anonymous> (/git/ts-unit-testing/spec/out/services/typescript-calculator.spec.js:14:17)
        at <Jasmine>

1 spec, 1 failure
Finished in 0.008 seconds
Randomized with seed 16618 (jasmine --random=true --seed=16618)
npm ERR! Test failed.  See above for more details.

Please check here for a complete code reference.

If you have any questions or suggestions please get in touch with me through LinkedIn or Twitter (the links below).

I wish you a happy coding.

Take care,
Ievgen