Mastodon Icon GitHub Icon LinkedIn Icon RSS Icon

Typescript Unit Test for Web Applications

You know, I quite enjoy TypeScript. It is not my favorite language ever, I am more a functional type of guy, but it is the best way to bring order into the JavaScript mess without too many hassles. Moreover, it is the language in which I prototyped my Astronomical Calendar Generator. Now that I’m working on extending it, I want to keep using TypeScript and stop falling in my usual decision paralysis. Anyway… First thing I needed to do is how to unit test a TypeScript source base. It is easy, but not intuitive. So let’s see how to do it.

There are two “problem” with TypeScript unit test when building a bundled JavaScript file for a web page. Problem A: you need a way to import directly the TypeScript code and write the tests in TypeScript too. It is logically the right thing to do. You can probably work with the output JS and write JS tests, but, come on…

Problem B is a bit more subtle. When you use TypeScript for a web page, the output get compiled in a monolithic file using some module system (in my case the require.js AMD format). When you test it, instead, you run your code in a Node.js instance that can not understand the AMD format (and you get the infamous define is not defined error).

Fortunately, we can solve these issues very easily. Let’s go step by step. Suppose you have a tsconfig.json file like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
    "compilerOptions": {
        "module": "amd",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "outFile": "build/app.js"
    },
    "files": \[
        "src/app.ts"
    \]
}

The first step is to install all the tools we need. I will use **mocha, chai, ts-node ** and amd-loader.

1
npm install -g mocha chai ts-loader amd-loader

The first two are one of the many suites for unit testing. ts-node is a tool for compiling on-the-fly TypeScript code commands. Imagine it as a REPL for TypeScript, it works exactly as node but you can write in TS. The last one, amd-loader is a tool that allow use to run mocha on the AMD output blob.

Now, we will install the type definitions for mocha and chai.

1
npm install @types/mocha @types/chai

We need these for writing TypeScript unit test (Problem A). At this point, we can create a folder tests and write our first test.

1
2
3
4
5
6
7
8
9
import { expect } from 'chai';
import 'mocha';

describe('Hello function', () => {
  it('return hello world', () => {
    const result = "Hello World!";
    expect(result).to.equal('Hello World!');
  });
});

If we need to import a custom function from our code base, we can use the usual TypeScript import pattern.

Now we need to run the tests with the following command:

1
mocha -r ts-node/register -r amd-loader ./tests/\*\*/\*

As you can see, before running tests, we need to tell mocha to “import” two libraries. ts-node/register, so that mocha can “understand” TypeScript code; and amd-loader, so that mocha can import AMD bundled modules.

That’s all!

comments powered by Disqus