Reader small image

You're reading from  Learning Angular - Fourth Edition

Product typeBook
Published inFeb 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781803240602
Edition4th Edition
Languages
Tools
Right arrow
Authors (2):
Aristeidis Bampakos
Aristeidis Bampakos
author image
Aristeidis Bampakos

Aristeidis Bampakos is a Web Development Team Lead at Plex-Earth who specializes in the development of web applications with Angular. He has been an Angular Google Developer Expert (GDE) since 2020 and works as an Angular Senior Tech Instructor at Code.Hub, a private educational institute, where he nurtures aspiring Angular developers and professionals. He is also the author of Angular Projects with Packt.
Read more about Aristeidis Bampakos

Pablo Deeleman
Pablo Deeleman
author image
Pablo Deeleman

With sound expertise in front-end libraries and frameworks such as Backbone.js, Knockout.js, VueJS, React, Svelte, AngularJs, and Angular, Pablo Deeleman has developed his career since 1998 as a JavaScript engineer across a broad range of successful companies such as Gameloft, Red Hat or Dynatrace, just to name a few. He currently works as Staff Software Engineer at Twilio, the global leader in customer engagement communications. Pablo Deeleman has contributed to the dev community with several books on Angular since 2016, all published by Packt Publishing.
Read more about Pablo Deeleman

View More author details
Right arrow

Introducing unit tests in Angular

In the previous section, we familiarized ourselves with unit testing and its general concepts, such as test suites, test specs, and assertions. It is time to venture into unit testing with Angular, armed with that knowledge. Before we start writing tests for Angular, though, let's have a look at the tooling that the Angular framework and the Angular CLI provide us to make unit testing a pleasant experience:

  • Jasmine: We have already learned that this is the testing framework
  • Karma: The test runner for running our unit tests
  • Angular testing utilities: A set of helper methods that assist us in setting up our unit tests and writing our assertions in the context of the Angular framework

When we use the Angular CLI, we do not have to do anything to configure Jasmine and Karma in an Angular application. Unit testing works out of the box as soon as we create a new Angular CLI project. Most of the time, we will interact...

Testing components

You may have noticed that every time we used the Angular CLI to scaffold a new Angular application or generate an Angular artifact, it would create some test files for us.

Test files in the Angular CLI contain the word spec in their filename. The filename of a test is the same as the Angular artifact that is testing, followed by the suffix .spec.ts. For example, the test file for the main component of an Angular application, app.component.ts, would be app.component.spec.ts and reside in the same path as the component file.

We should think about an Angular artifact and its corresponding test as one thing. When we change the logic of the artifact, we may need to modify the unit test as well. Placing unit test files with their Angular artifacts makes it easier for us to remember and edit them. It also helps us when we need to do some refactoring to our code, such as moving artifacts (not forgetting to move the unit test...

Testing services

As we learned in Chapter 6, Managing Complex Tasks with Services, a service can inject other services . Testing a standalone service is pretty straightforward: we get an instance from the injector and then start to query its public properties and methods.

We are only interested in testing the public API of a service, which is the interface that components and other artifacts use. Private symbols do not have any value in being tested because they represent the internal implementation of the service.

There are three different types of testing that we can perform in a service:

  • Testing a synchronous operation, such as a method that returns a simple array
  • Testing an asynchronous operation, such as a method that returns an observable
  • Testing services with dependencies, such as a method that makes HTTP requests

In the following sections, we will go through each of them in more detail.

Testing a synchronous method

When we create an Angular...

Testing pipes

As we learned in Chapter 5, Enrich Applications using Pipes and Directives, a pipe is a TypeScript class that implements the PipeTransform interface. It exposes a transform method that is usually synchronous, which means it is straightforward to test. The list.pipe.ts file contains a pipe that converts a comma-separated string into a list:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'list'
})
export class ListPipe implements PipeTransform {
  transform(value: string): string[] {
    return value.split(',');
  }
}

Writing a test for it is simple. The only thing that we need to do is to instantiate an instance of ListPipe and verify the outcome of the transform method with some mock data:

import { ListPipe } from './list.pipe';
describe('ListPipe', () => {
  it('create an instance&apos...

Testing directives

Directives are usually quite straightforward in their overall shape, being components with no view attached. The fact that directives usually work with components gives us a very good idea of how to proceed when testing them.

Consider the copyright.directive.ts file that we created in Chapter 5, Enrich Applications using Pipes and Directives:

import { Directive, ElementRef } from '@angular/core';
@Directive({
  selector: '[appCopyright]'
})
export class CopyrightDirective {
  constructor(el: ElementRef) {
    const currentYear = new Date().getFullYear();
    const targetEl: HTMLElement = el.nativeElement;
    targetEl.classList.add('copyright');
    targetEl.textContent = `Copyright ©${currentYear} All Rights Reserved.`;
  }
}

A directive is usually used in conjunction with a component, so it makes sense to unit test it while using it on a component. Let's create a test host component and add it to...

Testing forms

As we saw in Chapter 10, Collecting User Data with Forms, forms are an integral part of an Angular application. It is rare for an Angular application not to at least have a simple form, such as a search form. We have already learned that reactive forms are better than template-driven forms in many ways and are easier to test, so in this section, we will focus only on testing reactive forms.

Consider the following search.component.ts file:

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'app-search',
  template: `
    <form [formGroup]="searchForm" (ngSubmit)="search()">
      <input type="text" placeholder="Username" formControlName="searchText">
      <button type="submit" [disabled]="searchForm.invalid">Search</button>
    </form>
...

Summary

We are at the end of our testing journey, and it's been a long but exciting one. In this chapter, we saw the importance of introducing unit testing in our Angular applications, the basic shape of a unit test, and the process of setting up Jasmine for our tests.

We also learned how to write robust tests for our components, directives, pipes, and services. We also discussed how to test Angular reactive forms.

This unit testing chapter has almost completed the puzzle of building a complete Angular application. Only the last piece remains, which is important because web applications are ultimately destined for the web. Therefore, in the next chapter, we will learn how to produce a production build for an Angular application and deploy it to share with the rest of the world!

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learning Angular - Fourth Edition
Published in: Feb 2023Publisher: PacktISBN-13: 9781803240602
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Authors (2)

author image
Aristeidis Bampakos

Aristeidis Bampakos is a Web Development Team Lead at Plex-Earth who specializes in the development of web applications with Angular. He has been an Angular Google Developer Expert (GDE) since 2020 and works as an Angular Senior Tech Instructor at Code.Hub, a private educational institute, where he nurtures aspiring Angular developers and professionals. He is also the author of Angular Projects with Packt.
Read more about Aristeidis Bampakos

author image
Pablo Deeleman

With sound expertise in front-end libraries and frameworks such as Backbone.js, Knockout.js, VueJS, React, Svelte, AngularJs, and Angular, Pablo Deeleman has developed his career since 1998 as a JavaScript engineer across a broad range of successful companies such as Gameloft, Red Hat or Dynatrace, just to name a few. He currently works as Staff Software Engineer at Twilio, the global leader in customer engagement communications. Pablo Deeleman has contributed to the dev community with several books on Angular since 2016, all published by Packt Publishing.
Read more about Pablo Deeleman