Angular 8 Tutorial

Angular 8 Introduction History and versions of Angular 8 Architecture of Angular 8 How to install Angular 8 and set-up it. Creating our first Angular 8 app Angular 8 app loading

Difference between Angular And react

Angular vs react

Angular 8 Advantages Disadvantage

Advantage and Disadvantage of Angular 8

Angular 8 file structure

Angular 8 file structure

Angular 8 components

Components of Angular 8

Angular 8 CLI Commands

All CLI commands of Angular

Angular 8 with Bootstrap

How to install bootstrap for Angular 8 Libraries of Angular 8

Angular 8 Routing

Routing in Angular 8

Angular 8 directives

Angular 8 Directives Angular 8 ngIf directive Angular 8 ngFor directive Angular 8 ngSwitch directive Angular 8 ngClass directive Angular 8 ngStyle directive

Angular 8 pipes

Angular 8 Pipes

Angular 8 databinding

Angular 8 Data binding Angular 8 Event binding Angular 8 Property binding Two-way data binding in Angular 8

String Interpolation In Angular 8

Angular 8 String interpolation

Angular 8 forms

Angular 8 Forms Data flow of forms in Angular 8 Creating forms in Angular 8 Testing and validation of forms in Angular 8

Error fixing in Angular 8

Error fixing in Angular 8

Dependency injection and services in Angular 8

Dependency injection services in Angular 8

Angular 8 Animations

Angular 8 Animations

Dynamic components in Angular 8

Dynamic components in Angular 8

Angular 8 Module

Angular 8 Module Deploying an angular 8 app

Introduction of unit testing in angular 8

Unit testing in angular 8

Observables in angular 8

Observables in angular 8

Angular 8 universal

Angular 8 universal

Angular 8 Changes and new features

New features and changes in Angular 8

Conclusion

Angular 8 Conclusion

Angular 8 Unit Testing

What is unit testing?

Unit testing is a type of software testing where individual components of the software are tested. It is done during the development of any application. A unit may be a particular program, function, procedure etc.

Angular Unit Testing

In Angular 8, Unit testing created with the help of Angular CLI. This sample application and all tests in this guide are available for inspection and experimentation:

Setup

The Angular CLI downloads and install everything we need to test an Angular app with the Jasmine test framework.

The project we create with the help of CLI is immediately ready to test. Just run the ng test CLI (command line interface).

ng test

The ng test command built the app in silent mode and launched the Karma test runner in the file.

The console output looks like below code:

10% building modules 1/1 modules

...INFO [karma]: Karma v1.7.1 server has started in the localhost  http://0.0.0.0:9876/

...INFO [launcher]: Launch the browser Chrome ...

...INFO [launcher]: Start the browser Chrome

...INFO [Chrome ...]: Connect on the socket ...

Chrome ..: Executed 3 of 3 SUCCESS (0.185 secs / 0.303 secs)

The final line of the log is essential. It shows that the Karma ran three tests which passed in the test.

A chrome browser also displays the test output in the "jasmine HTML Reporter".

jasmine HTML Reporter

Most people find this browser output more comfortable to read than the console log. We can click on a test row to re-run just that test or click on a description to re-run the criteria in the selected test group (“test suite”).

To see this action, make a small change in app.component.ts and save. The tests run again, and then the browser refreshes, and the new test results appear.

Why we use unit testing in Angular 8?

Why we use unit testing in Angular 8

Configure the project for circle CI

The CLI take care of Jasmine and Karma configuration.

Step 1: Create a folder named .circle ci in the project root file.

Step 2: In a new folder, create a file named config.yml with the given below content:

version: 2
 jobs:
 build:
     working_directory: ~/my-project
     docker:
       - image: circleci/node:10-browsers
     steps:
       - checkout
       - restore_cache:
           key: my-project-{{ .Branch }}-{{ checksum "package-lock.json" }}
       - run: npm install
       - save_cache:
           key: my-project-{{ .Branch }}-{{ checksum "package-lock.json" }}
 paths:
 - "node_modules"
 - run: npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
 - run: npm run e2e -- --protractor-config=e2e/Protractor-ci.conf.js 

This configuration cache node_modules/and uses npm to run CLI commands, because @angular/cli is not installed globally. The double dash (--) is needed to pss arguments into the npm script.

Step 3: Commit our changes and push them to your repository.

Step 4: Sign up Circle CI and add our project, our project should start building.

Configuring project for Travis CI file

Step 1: firstly, create a file called .travis.yml at the project root, with the below content:

dist: trusty
 sudo: false
 language: node_js
 node_js:
   - "10"
 addons:
   apt:
     sources:
       - google-chrome 
     packages:
       - google-chrome-stable
 cache:
   directories:
      - ./node_modules
 install:
   - npm install 
 script:
   - npm run test ----no-watch --no-progress --browsers=ChromeHeadlessCI
   - npm run e2e ----protractor-config=e2e/protractor-ci.conf.js 

It does the same things like the circle CI configuration, except that Travis doesn't come with chrome, so we use chromium instead.

Step 2: Commit our changes and push them to our repository.

Step 3: Sign up the Travis CI and add our project.

Configure CLI for CI testing in the Chrome

When both CLI commands ng test and ng e2e are running in CI test in the environment, we have to adjust the configuration to run into the Chrome browser test.

There are configuration files for both Karma JavaScript test runner and Protractor end-to-end testing tool, which we must adjust to starting Chrome without sandboxing.

browsers: ['Chrome'],
 customLaunchers: {
   ChromeHeadlessCI: {
     base: 'ChromeHeadless',
     flags: ['--no-sandbox']
   }
 },  
  • In the root folder of our e2e tests project, create a new file named proctractor-ci.config.js. This new file can extends the original protractor.conf.js.
const config = require('./protractor.conf').config;
 config.capabilities = {
   browserName: 'chrome',
   chromeOptions: {
     args: ['--headless', '--no-sandbox']
   }
 };
 exports.config = config; 

Service Tests

Services are often the earliest files to unit test. There are some synchronous and asynchronous unit tests of the ValueService written without assistance from Angular testing utilities.

app/demo/demo.spec.ts

// Straight Jasmine testing without Angular's test  
 describes('ValueService', () => {
 let service: ValueService;
 beforeEach(() => { service = new ValueService(); });
 it('#getValue should return real value', () => {
 expect(service.getValue()).toBe('real value'); 
   });
 it('#getObservableValue should return value from observables' 
 (done: DoneFn) => {
 service.getObservableValue().subscribe(value => {
 expect(value).tobe('observablevalue');
 done();
 }); 
 });
  it('#getPromiseValue should return value from promise', 
     (done: DoneFn) => {
     service.getPromiseValue().then(value => {
       expect(value).toBe('promise value');
       done(); 
  }); 
  }); 
 }); 

Services with dependencies

Services depend on other services where Angular injects into the constructor. In many cases, it is easy to create and inject these dependency by hand while calling the service's constructor.

This is a simple example:

@Injectable()
 export class MasterService {
   constructor(private valueService: ValueService) { }
   getValue() { return this.valueService.getValue(); }
 } 

MasterService delegates only method, getValue, to the injected ValueService.

Here are several ways to test it.

app/demo/demo.spec.ts

describe('MasterService without Angular testing support', () => {
   let masterService: Master Service;
  it('#getValue can return real value from real service', ( ) => { 
     masterService = new MasterService(new ValueService( ));
     expect(masterService.getValue()).tobe('real value');
   });
   it('#getValue should return fakevalue from a fake Service', () => {
     masterService = new MasterService(new FakeValueService());
     expect(masterService.getValue()).toBe('fake service value');
   });
 it('#getValue should return fake value from a fake object', () => {  
     const fake =  { getValue: () => 'fake value' };
     masterService = new MasterService(fake as ValueService);
     expect(masterService.getValue()).toBe('fake value');
   });
 it('#getValue should return stub value from a spy', () => { 
 const valueServiceSpy = 
 jasmine.createSpyObj('ValueService', ['getValue']);
    const stubValue = 'stub value';
     valueServiceSpy.getValue.and.returnValue(stubValue);
  masterService = new MasterService(valueServiceSpy);
 expect(masterService.getValue())
       .toBe(stubValue, 'service returned stub value');
     expect(valueServiceSpy.getValue.calls.count()) 
       .toBe(1, 'spy method was called once');
     expect(valueServiceSpy.getValue.calls.mostRecent().returnValue)
       .toBe(stubValue);
   });
 }); 

Testing Services with the TestBed

When a service has a dependency service, DI (dependency injection) finds or creates that dependent service.

Angular TestBed

The TestBed is most famous for the Angular testing utilities. The TestBed creates a dynamic-constructed Angular test module that emulates an Angular @NgModule.

To test service, we set the providers metadata property with an array of the services that we will verify or mock.

Let service: ValueService;
beforeEach(() => {
  TestBed.configureTestingModule({ providers: [ValueService] });
}); 

Then inject it in a test by calling TestBed.get() with the service class as the argument.

it('should use ValueService', () => {
  service = TestBed.get(ValueService);
  expect(service.getValue()).toBe('real value');
 }); 

Or it use inside beforeEach( ) if we prefer to inject the service as part of our setup.

beforeEach(() => {
   TestBed.configureTestingModule({ providers: [ValueService] });
   service = TestBed.get(ValueService);
 }); 

When testing a service with any dependency, get the mock in the providers array.