Angular Unit Testing

Hi geeks welcome to the first part of angular unit testing tutorials. During the tutorials, I will demonstrate how we can test our Angular application.

Angular and like every other front-end framework, provide us with a test suite So that testing becomes an easy step.

Tools

There are a number of testing libraries and frameworks we can use which reduce the amount of time it takes to write tests . Krama & Jasmine are the ones used by Angular to do the job.

unit testing

Jasmine  :

Jasmine is a javascript testing framework that supports a software development practice called Behaviour Driven Development, or BDD for short. It’s a specific flavour of Test Driven Development (TDD).

Jasmine, and BDD in general, attempts to describe tests in a human readable format so that non-technical people can understand what is being tested. However even if you are technical reading tests in BDDformat makes it a lot easier to understand what’s going on.

Example :

// simple function that we want to test 
function helloWorld() {
  return 'Hello world!';
}

// the jasmine test code is 
describe('Hello world', () => { 
  it('says hello', () => { 
    expect(helloWorld()) 
        .toEqual('Hello world!'); 
  });
});
  • The describe(string, function) function defines what we call a Test Suite, a collection of individual Test Specs.
  • The it(string, function) function defines an individual Test Spec, this contains one or more Test Expectations.
  • The expect(actual) expression is what we call an Expectation. In conjunction with a Matcher it describes an expected piece of behaviour in the application.
  • The matcher(expected) expression is what we call a Matcher. It does a boolean comparison with the expected value passed in vs. the actual value passed to the expect function, if they are false the spec fails.

Some built-in matchers : 

expect(array).toContain(member);
expect(fn).toThrow(string);
expect(fn).toThrowError(string);
expect(instance).toBe(instance);
expect(mixed).toBeDefined();
expect(mixed).toBeFalsy();
expect(mixed).toBeNull();
expect(mixed).toBeTruthy();
expect(mixed).toBeUndefined();
expect(mixed).toEqual(mixed);

You can see concrete examples of how these matchers are used by looking at the Jasmine docs here: http://jasmine.github.io/edge/introduction.html#section-Included_Matchers

Setup & teardown :

More often in our test, we want to do some logic before running a spec of test(setup) or do some cleaning after running a test spec (teardown). Jasmine comes with useful methods that we can use out of the box:).

  •  beforeAll

This function is called oncebefore all the specs in describe test suite are run.

  • afterAll

This function is called once after all the specs in a test suite are finished.

  • beforeEach

This function is called before each test specification, it function, has been run.

  • afterEach

This function is called after each test specification has been run.

 

Testing a class

In Angular everything is a class so how we can test one?

For the purpose of this tutorial let’s have an example :

The AuthService class  

It is a simple class that has one method.

export class AuthService {
  isAuthenticated(): boolean {
    return !!localStorage.getItem('token'); 
  }
}

The Auth service Test 

authService.spec.ts

NB: The name of the file has to have the .spec part before the extension .ts

import {AuthService} from './AuthService';

describe('Service: Auth', () => {
  let service: AuthService;    // define an instance of our class 

  beforeEach(() => {
    service = new AuthService();   // instantiate an instance of our class before each test 
  });

  afterEach(() => {
    service = null;      // cleaning the instance after each test 
    localStorage.removeItem('token');
  });
  it('should return true from isAuthenticated when there is a token', () => {
    localStorage.setItem('token', '1234');
    expect(service.isAuthenticated()).toBeTruthy();
  });

  it('should return false from isAuthenticated when there is no token', () => {
    expect(service.isAuthenticated()).toBeFalsy();
  });

});

OK ibrahim but how can I run the test?

open the terminal and run the following command : ng test ( this will open the browser and run all of your specs)

NB :  you can disable a test and igonre it by adding x before decribe . Also you can add f to just focus in that test .

 // this test will not run because we add the x 
xdescribe('Hello world', () => { 
  xit('says hello', () => { 
    expect(helloWorld())
        .toEqual('Hello world!');
  });
});
// this is the only test that will run unless there are other tests that have the f too .
fdescribe('Hello world', () => { 
  xit('says hello', () => { 
    expect(helloWorld())
        .toEqual('Hello world!');
  });
});

So this was a little introduction to unit test . Happy coding and see you soon !