Angular 2 Component Testing using Jasmine

Tags: angular2
Question!

I am working on the Final Release of the Angular 2 for component testing. I am able to run my application but when I run the Test, The browser shows the following result Error Message After Viewing Test in Browser

The Systemjs.config.js is as following

var map = {
	"rxjs": "node_modules/rxjs",
	"@angular/common": "node_modules/@angular/common",
	"@angular/forms": "node_modules/@angular/forms",
	"@angular/compiler": "node_modules/@angular/compiler",
	"@angular/core": "node_modules/@angular/core",
	"@angular/platform-browser": "node_modules/@angular/platform-browser",
	"@angular/testing":"node_modules/@angular/core/testing",
	"@angular/platform-browser-dynamic": "node_modules/@angular/platform-browser-dynamic",
};
var packages = {
	"rxjs": { "defaultExtension": "js" },
	"@angular/common": { "main": "bundles/common.umd.js", "defaultExtension": "js" },
	"@angular/forms": { "main": "bundles/forms.umd.js", "defaultExtension": "js" },
	"@angular/compiler": { "main": "bundles/compiler.umd.js", "defaultExtension": "js" },
	"@angular/core": { "main": "bundles/core.umd.js", "defaultExtension": "js" },
	"@angular/platform-browser": { "main": "bundles/platform-browser.umd.js", "defaultExtension": "js" },
	"@angular/platform-browser-dynamic": { "main": "bundles/platform-browser-dynamic.umd.js", "defaultExtension": "js" },
	"@angular/testing" : {"main": "testing.js", "defaultExtension": "js"},
	"app": {
		format: 'register',
		defaultExtension: 'js'
	}  
};

var config = {
	map: map,
	packages: packages
};

System.config(config);

The apptester.html is as following

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8">
  <title>Ng App Unit Tests</title>
  <link rel="stylesheet" href="./node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
  <script src="./node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
  <script src="./node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
  <script src="./node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
  <script src="node_modules/es6-shim/es6-shim.min.js"></script>
  <script src="node_modules/zone.js/dist/zone.js"></script>
  <script src="node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
  <script src="node_modules/zone.js/dist/proxy.js"></script>
  <script src="node_modules/zone.js/dist/sync-test.js"></script>
  <script src="node_modules/zone.js/dist/jasmine-patch.js"></script>
  <script src="node_modules/reflect-metadata/Reflect.js"></script>
 <script src="node_modules/systemjs/dist/system.src.js"></script>  
</head>
<body>
  <script src="systemjs.config.js"></script>
  <script>
    System.import('./app/app.component.spec')
       .then(window.onload)
       .catch(console.error.bind(console));
  </script>
</body>
</html>

The Test Code in app.component.spec.ts is as following

import {inject,TestBed,ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {EmployeeComponent} from './app.component';
import {Employee} from './employee.model';
describe('EmployeeComponent', () => {
  let employee;
  let app;
  let fixture: ComponentFixture<EmployeeComponent>;
  beforeEach(() => {
    employee = new Employee();
//    app = new EmployeeComponent();
    TestBed.configureTestingModule({
      declarations: [EmployeeComponent],
    });
    TestBed.compileComponents();
       fixture = TestBed.createComponent(EmployeeComponent);
       app = fixture.componentInstance;
       console.log('In describe');
  });
it('getTax', () => {
    employee.designation = "Manager";
    employee.salary = 40000;
    let res = 12111000;
    app.emp = employee;
    fixture.detectChanges();
    let actRes = app.getTax();
    expect(actRes).toEqual(res);
  });
});

The Same code works in RC 1 and 2 release but not in Angular 2 final release. My package.json is as following

{
  "name": "ng2-databinding-application",
  "version": "1.0.0",
  "scripts": {
    "start": "concurrently \"tsc -w\" \"node server.js\"",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "typings": "typings",
    "postinstall": "typings install"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/core": "2.0.0",
    "@angular/forms": "2.0.0",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/router": "3.0.0",
    "@angular/upgrade": "2.0.0",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.23",
    "angular2-in-memory-web-api": "0.0.20",
    "bootstrap": "*",
    "es6-shim": "^0.35.0",
    "koa": "^1.2.0",
    "koa-static": "^2.0.0",
    "livereload": "^0.4.1",
    "jasmine-core": "2.5.1",
    "typescript": "^2.0.2",
    "typings": "^1.3.2"
  },
  "devDependencies": {
    "concurrently": "^2.2.0",
    "jasmine-core": "^2.5.1",
    "lite-server": "^2.1.0",
    "node-gyp": "^3.3.1",
    "typescript": "^2.0.2",
    "typings": "^1.3.2"
  }
}

By : Mahesh S


Answers

The problem comes from your systemJS config, let me explain this.

You added @angular/testing as package, which is nice, but you told systemJS that he could find the main JS in testing.js.

So, when you do import{Foo} from "@angular/testing"; systemJS will get node_modules/@angular/testing/testing.js to import it.

Simply set the main attribute of your @angular/testing entry to index.js and it will work fine:

var packages = {
    ...
    ...
    "@angular/testing" : {"main":"index.js", "defaultExtension": "js"},
    ...
    ... 
};

EDIT: if you want the bundled version to be imported:

var packages = {
    ...
    ...
    "@angular/testing" : {"main":"bundles/testing.umd.js", "defaultExtension": "js"},
    ...
    ... 
};
By : Supamiu


While this is perfectly valid it breaks modularity. A component can style its own root-element:

my-page.component.css

:host{
  background-color: grey;
}

header {
    ...
}

.sticky-footer {
    position: absolute;
}

This will achieve the same thing and contains CSS that's vital to your MyPageComponent in the component.

By : j2L4e


If you have to pass multiple parameter please use class object:

public class PortalClass
{
    public ApplicationModel applicationModel { get; set; }
    public string user_id { get; set; }
    public string id { get; set; }
    public object pageCollection { get; set; }
}

public object GetApplication(PortalClass data)
{
    JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, PreserveReferencesHandling = PreserveReferencesHandling.None };
    var myObject=JsonConvert.DeserializeObject<PageCollection>(data.pageCollection.ToString(), settings)
    return null;
}

Client Side:

var data = {
    user_id: userId,
    id: id
};

http.post(url, data).then(
   function (response) {

}, function (err) {
   callback.reject(err);
});


This video can help you solving your question :)
By: admin