Run Unit Tests On Angular 2 Quick-Start Example With Jasmine & Karma

What I have done beforehand

  1. Followed the instructions to set up my Visual Studio 2015;
  2. Checked out the Quick Start Example, and after solving some unexpected issues, I can run it;
  3. I walked through the instructions for running unit tests with Karma.

That is the starting point of this blog.

The Problem

I run the command

npm test

run-test.png

It launches the Karma tab in Chrome, but it does not work, and I got errors from the cmd prompt:

error-in-karma.png

It says:

[1] 21 07 2017 16:10:13.532:WARN [web-server]: 404: /node_modules/@angular/core/bundles/core-testing.umd.js
[1] 21 07 2017 16:10:13.548:WARN [web-server]: 404: /node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js
[1] Chrome 59.0.3071 (Windows 7 0.0.0) ERROR: 'Unhandled Promise rejection:', '(SystemJS) XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error: XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js', '; Zone:', 'root', '; Task:', 'Promise.then', '; Value:', Error{originalErr: Error{__zone_symbol__currentTask: ZoneTask{_zone: ..., runCount: ..., _zoneDelegates: ..., _state: ..., type: ..., source: ..., data: ..., scheduleFn: ..., cancelFn: ..., callback: ..., invoke: ...}}, __zone_symbol__currentTask: ZoneTask{_zone: Zone{_properties: ..., _parent: ..., _name: ..., _zoneDelegate: ...}, runCount: 0, _zoneDelegates: null, _state: 'notScheduled', type:'microTask', source: 'Promise.then', data: undefined, scheduleFn: undefined, cancelFn: null, callback: function () { ... }, invoke: function () { ... }}}, '(SystemJS) XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error: XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js'
[1]
[1] Chrome 59.0.3071 (Windows 7 0.0.0) ERROR: 'Unhandled Promise rejection:', '(SystemJS) XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error: XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js', '; Zone:', 'root', '; Task:', 'Promise.then', '; Value:', Error{originalErr: Error{__zone_symbol__currentTask: ZoneTask{_zone: ..., runCount: ..., _zoneDelegates: ..., _state: ..., type: ..., source: ..., data: ..., scheduleFn: ..., cancelFn: ..., callback: ..., invoke: ...}}, __zone_symbol__currentTask: ZoneTask{_zone: Zone{_properties: ..., _parent: ..., _name: ..., _zoneDelegate: ...}, runCount: 0, _zoneDelegates: null, _state: 'notScheduled', type:'microTask', source: 'Promise.then', data: undefined, scheduleFn: undefined, cancelFn: null, callback: function () { ... }, invoke: function () { ... }}}, '(SystemJS) XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error: XHR error (404 Not Found) loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js
[1]     Error loading http://localhost:9876/node_modules/@angular/core/bundles/core-testing.umd.js'
[1] 21 07 2017 16:10:23.557:WARN [Chrome 59.0.3071 (Windows 7 0.0.0)]: Disconnected (1 times), because no message in 10000 ms.
[1] Chrome 59.0.3071 (Windows 7 0.0.0) ERROR
[1]   Disconnected, because no message in 10000 ms.
[1]
[1] Chrome 59.0.3071 (Windows 7 0.0.0) ERROR
[1]   Disconnected, because no message in 10000 ms.
[1]
[1] 21 07 2017 16:15:29.135:WARN [web-server]: 404: /node_modules/@angular/core/bundles/core-testing.umd.js

The files it fails in loading are just right there, as I have ran the npm command to install the packages:

file.png

The Solution

Open the config file: /src/systemjs.config.js, change the value of path to be:

paths: {
  'npm:': '/base/node_modules/'
},

The whole file reads as:

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': '/base/node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      'app': 'app',

      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

      // other libraries
      'rxjs':                      'npm:rxjs',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        defaultExtension: 'js',
        meta: {
          './*.js': {
            loader: 'systemjs-angular-loader.js'
          }
        }
      },
      rxjs: {
        defaultExtension: 'js'
      }
    }
  });
})(this);

Re-start the Karma service, and I can run sample unit test: true is true, as well as other tests of my service classes, keep in mind that you will need to undo the change to be able to build & run the app.

However, I got errors running the test of my component, as it uses an external html as template and a css file for styling, these files are all under /src/app/.

My component class looks like:

// imports...

@Component({
    selector: 'my-app',
    templateUrl: 'app/app.component.html',
    styleUrls: ['app/app.component.css'],
    providers: [RuntimeSettingsService]
})
export class AppComponent implements OnInit {
	//...
}

This works fine when building the app, but it causes the problem when running the tests. A better way is use relative path, as the official sample shows:

// imports...

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    providers: [RuntimeSettingsService]
})
export class AppComponent implements OnInit {
	//...
}

In the case of unit test, its path should be base/src/app/app.component.html. The relative path works for both building and testing, otherwise you would have to keep changing the paths forth and back as you switch between develop and unit test.

You need to re-start Karma, and even reboot your pc sometimes to get it to work.

Reference

My question on stackoverflow.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s