Testing in Angular 2
Angular 2.0 is JavaScript based, open source, client-side and server-side web application framework. Compared to angular1 a lot has changed in Angular 2.0, so in this article I will explain how to unite test Angular 2.0 code using Jasmine and TypeScript. We will wrtite test cases to explore and confirm the behaviour of our application. JavaScript framework is a dynamically typed language which comes with great power of logics and expression, but it also comes with nearly no help from the compiler. For this primary reason we feel very strongly that any code written in JavaScript language or framework needs to come with a strong set of validation tests. The Google and angular2 community have built many new features into Angular2 which makes testing an Angular2 application easy and faster. With Angular2, there is no excuse for not testing an application.
Why testing is necessary in our application:
- Test cases protect against breaking existing code when we make any changes.
- Test cases clarify what the code does both when used as planned and when faced with complex conditions.
- Test cases reveal mistakes in application design and implementation. Tests force us to look at our code from different angles and approaches. When a part of our application seems tough to test, we may have found a design bug, something we can resolve now rather than later when it becomes expensive to fix.
Tools for testing Angular applications:
Karma
Karma is a product of the Google AngularJS team for testing their own javascript framework features with existing tools. As a result of this, the Angular team made the Karma testing tool and rightly suggest it as their preferred test runner tool within the Angular2 JS documentation.
Karma is essentially a tool which generates a web server that executes our source code against test cases code for each of the browsers connected. The results of each test case against each web browser are examined and displayed via the command line tool to the developer so that they can see which browsers and tests passed or failed.
A web browser can be snatched either manually, or by visiting the URL where the Karma server is listening or located (typically http://localhost:9876/), or automatically by letting Karma tool know which browsers to start when Karma is in operation.
Karma also watches all the files, specified within the configuration file of the application, and whenever any file changes, it triggers the test run by sending a signal to the test server to inform all of the captured browsers to re-run the test code again. Each test browser then loads the source files inside an iFrame, executes the tests and reports the results back to the server.
Jasmine is a behavior driven development framework for JavaScript that has become the most popular choice for testing Angular applications. Jasmine does not need any other JavaScript frameworks and it does not require a Document Object Model (DOM). And it has a clean, clear obvious syntax so that you can easily write test cases. Jasmine provides functions to help with structuring your tests cases and also making assertions. As your test cases grow, keeping them well structured and documented is necessary and vital, and Jasmine tool helps us to achieve this.
In Jasmine we use the describe() method to group our tests together:
describe (“sorting the list of users”, function() {
//individual tests go here
});
And then each individual test is defined within a call to the it() function:
describe (‘sorting the list of users’, function() {
It(‘sorts in descending order by default’, function() {
//your test assertion goes here
});
});
Grouping related tests within described blocks and describing each individual test within an it call keeps your tests self documenting.
Finally, Jasmine provides matchers which let you make assertions:
describe( ‘sorting the list of users’ , function() {
it( ‘sorts in descending order by default’ , function () {
var user = [‘jack’, ‘igor’ , ‘jeff’ ];
var sorted = sortUsers(users);
expect(storted).toEqual ([‘jack’, ‘igor’ , ‘jeff’ ]);
});
});
Jasmine comes with a number of matchers that help you make a variety of assertions. You should read the Jasmine documentation to see what they are. To use Jasmine with Karma, we use the karma-jasmine test runner.
Let’s learn how to test a simple angular2 component.
Angular2 components are made up of classes, and our component testing strategy revolves around validating the correctness of the properties, functions and methods of those classes. In Angular 2, a component's class will often depend on some dependencies – angular service, directive, pipe, RxJS etc. When writing unit tests cases for components we don't actually bootstrap the application, instead we initialize the angular2 component (AppComponent) and inject any dependencies manually. We don’t need to bootstrap like angular1 but we make an explicit call to AppComponent. Once we get an instance of the Angular2 component we can call its methods and check the values of its properties, and query whatever output it has made to the Document Object Model (DOM).
Let's take a look at a basic component testing that we will write some unit tests for.
I have written a simple case for unit testing of a component without dependencies. Let’s create a DisplayName component. As you can see the DisplayName component to display the full name of a person.
Testing DisplayName Component :-
import {Component,Input} from '@angular/core';
@Component({
selector:'display-name',
templateUrl: './my-template.html'
})
export class DisplayName{
@Input() firstName:string;
@Input() lastName:string;
fullName:string;
generateFullName(){
this.fullName = this.firstName + ' ' + this.lastName;
}
}
So let’s write a test case for this DisplayName Component. So first install jasmine in your application
npm install jasmine-core --save-dev --save-exact
So this is our test case. You can see that the entire test is wrapped around the main() function. This is an angular convention used by angular team
There are two types of test in the above example:-
- Manually instantiate DisplayName Component
- Use Dependency injection to instantiate Component.
import {describe,expect,it,xit, inject, beforeEachProviders} from '@angular/core/testing';
import {DisplayName} from './display-name';
export function main() {
describe('DisplayName', () => {
beforeEachProviders(() => [
DisplayName
]);
//Manually instantiate DisplayName
it('should define full name', () => {
let displayName = new DisplayName();
displayName.firstName = 'Joe';
displayName.lastName = 'Smith';
displayName.generateFullName();
expect(displayName.fullName).toBe('Joe Smith');
});
//Use DI to instantiate DisplayName
it('should define full name2', inject([DisplayName], (displayName) => {
displayName.firstName = 'Joe';
displayName.lastName = 'Smith';
displayName.generateFullName();
expect(displayName.fullName).toBe('Joe Smith');
}));
});
}
The first method is the most candid since it simply instantiates the component class manually before calling the generate FullName() method and an expect on the fullName property. This expects match the final result.
In the second method of the test I have made use of Dependency injection to initialize the component class. It requires a few more setup code since we have to tell Angular2 how to inject the component.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment