DEV Community

Dima Kuzmich
Dima Kuzmich

Posted on • Originally published at Medium on

Test Angular2 now or how to set up Angular2 unit tests

angular

Currently, I’m working on a project and I decided to build it with Angular2. It was a brave decision. It’s really not as simple as it looks when you try to build something with alpha versions of new technology. Loads of changes that part of them are breaking, difficulty in lack of documentation. Nevertheless, it’s incredibly exciting to see how Angular is growing up, to observe a collaboration of the team, and to feel a part of this interesting process.

One of the tasks that weren’t trivial for me is to set up the unit tests for my project. That’s the reason for my decision to describe this process. So let’s begin:

TypeScript

As Microsoft published nearly half-a-year ago, Angular2 is written in TypeScript. At the beginning that was a piece of shocking news for me. But later on, I’ve understood this step. I checked out a new version of TypeScript and was surprised to discover that it’s pretty close to ES6, erhh… JavaScript 2015?!.. Mmm… never mind, the latest JavaScript version :-) It also brings additional features, such as optional types, annotations, and more. These facts were convincing enough to try to write my project with TypeScript. I think that it is pretty clear, that if a code is written in TypeScript, tests should be written in TypeScript as well. If the tests are written in TypeScript, I should transpile them into ES5. And so I did with two tasks of Gulp:

gulp typescript tests build

Source code is here.

Karma

Karmais a test runner that was developed by the Angular team during the development of Angular.js. Among its main features is the ability to run tests fast and on real browsers. Also, it’s agnostic to the testing framework so that you can use whatever framework you’d like. I chose a Jasmine, but you can easily switch it to another one. So I installed Karma and Jasmine on my environment and started to set up my first test. here is an interesting part of the file:

karma config

Source code is here.

First of all, we need to add traceur-runtime.js. These are basically polyfills that allow us to use ES6 features in the browser despite their not being implemented yet.

Then we add our source files. The files should already be transpiled into ES5 code and should be only served by Karma and not actually be included with a script tag. That’s because we will import them into the tests using System.js.

And here they are es6 module loader and system.js files. System.js is a universal dynamic module loader that loads ES6 modules, AMD, CommonJS, and global scripts in the browser and NodeJS. Later on, we will see how to configure System.js to work with our tests properly.

We should definitely add an angular2 file :-) and then our test files. They also should be served and not included.

Surely, you noticed this test-main.js file that I included but didn’t explain. This file is the highlight of this post! So, Ladies and Gentlemen please welcome:

The System.js hook

As I said before, in order to support modules’ imports we use System.js. Currently, Karma does not support this feature, so that we need to implement some workaround that will be able to import all needed modules and only then to run our tests. Here is what we need to do:

karma systemjs hook

First of all, you should stop karma from executing. This is made by

\_\_karma\_\_.loaded = function () { };

Next, we should configure our system.js with appropriate files by setting baseUrl and paths properties of System global object.

System.baseURL = ‘/base/scripts/’;
System.paths = {
 ‘test/\*’: ‘/base/scripts/test/\*.js’,
 ‘build/\*’: ‘/base/scripts/build/\*.js’,
 ‘angular2/\*’: ‘angular2/\*’,
 ‘rx’: ‘rx’
};

Then we take all files that served by Karma, filter only test files, normalize file names to module names and import them one-by-one using System.import method.

One important thing to notice: each test file has to export the main function that includes whole tests related to a module. When the module is imported, we run its main method in order to expose the tests. Here is an example of a test module:

test example

Lastly, when entire tests were imported and exposed we run the karma engine:

\_\_karma\_\_.start(); // after all tests were exposed

And voilà, our Angular2 test environment is ready!

You can find the source code on Github. To set up the environment, just clone the repository and run:

$ npm start

Also, you are welcome to check out an angular-starter that my college Elad and I developed. It’s really simple and uses gulp for a build workflow.

I’ve based my test environment on an angular test environment. You can find their tests-main.js here.

One more thing, if you liked this post, please share it. For any question, you can find @me on Twitter


Top comments (0)