Testing Modular Client-Side TypeScript Code

December 17th 2016 Unit Testing TypeScript

In my previous posts I've already addressed unit testing of client-side JavaScript and TypeScript code, however since browsers don't natively support the ECMAScript 6 module system, simply transpiling the code is not enough for the tests to run in the browser.

Let's create a minimalistic example to try it out. First, a TypeScript module to test, src\multiply.ts:

export class Math {
  multiply(a: number, b: number): number {
    return a * b;
  }
}

Then, the corresponding test file, test\test-multiply.ts:

import { Math } from '../src/multiply';

describe('multiply method', () => {
  it('multiplies 2 numbers', () => {
    let math = new Math();
    expect(math.multiply(2, 5)).toBe(10);
  });
});

With typescript preprocessor configured, Karma will fail with a somewhat cryptic error message:

Chrome 55.0.2883 (Windows 10 0.0.0) ERROR
  Uncaught ReferenceError: exports is not defined
  at src/multiply.js:7

This happens, because the browser doesn't know about modules and can't resolve the dependencies. Karma will need to do that, instead. We'll use browserify to do it.

Let's start by installing the required npm modules:

npm install --save-dev browserify
npm install --save-dev watchify
npm install --save-dev tsify
npm install --save-dev karma-browserify

With that out of the way, it's time to configure browserify in karma.conf.js:

// register it as a framework
frameworks: ['browserify', 'jasmine'],
// only test files need to be loaded in the browser
files: [
  './test/*.ts'
],
// preprocess the files with browserify instead of typescript
preprocessors: {
  '**/*.ts': ['browserify']
},
// configure browserify to transpile typescript
browserify: {
  debug: true,
  plugin: [
    ['tsify', { target: 'es5' }]
  ]
},

This should be enough to get it working, however in recent versions of Chrome no tests get loaded:

Chrome 55.0.2883 (Windows 10 0.0.0): Executed 0 of 0 ERROR (0.002 secs / 0 secs)

Checking the Chrome DevTools JavaScript Console, explains this in a way:

Refused to execute script from 'http://localhost:9876/base/test/test-multiply.ts' because its MIME type ('video/mp2t') is not executable.

Fortunately, this can be fixed with more Karma configuration:

mime: {
  'text/x-typescript': ['ts']
},

Finally, the test gets run as expected:

Chrome 55.0.2883 (Windows 10 0.0.0): Executed 1 of 1 SUCCESS (0.005 secs / 0.001 secs)
Copyright
Creative Commons License