Learning and Implementing Unit Testing in an Angular Project

Renan Ferro - Jan 12 '23 - - Dev Community

Hey dude, how are you?!

First happy new year and let's make this year awesome! πŸŽ‰

Today I want to chat about Tests, Unit Tests and how important and cool it's to do this! And we’ll write a simple Unit Test with Angular and Jasmine!

So let's start!

πŸ‘¨πŸ½β€πŸ« A litte conversation about Unit Test

In a nutshell(My opinion too) tests are important and really necessary, unfortunately when we're coding our application we can't stop to write a test because sometimes the sprint time can be short! But tests are really cool, interesting and give our application the security about the code!

Unit Test is like to test each or an individual part of our application (For example: Component, Service, etc). The goal is to validate de code and ensure it works correctly.


πŸ“¦ Angular Tests

With Angular we can use Jasmine to write our tests and Angular uses Karma as the test runner. The Angular CLI downloads and installs everything we need to make our tests on our application!

When we use the Angular CLI and create something else like component, service if we repair is created a .spec.ts file! It's the file to us write the tests!


🧩 Our Case Study

Case Study: Let's create a service to receive a nickname and make a "sanitization" in the nickname! The service needs to return us a nickname with no empty values, in lowercase and have a prefix dev-to in front of the nick.

So we need to make the steps below:

  • πŸ“Œ create a service called by NicknameManager.
  • πŸ“Œ create a getSanitizedNick() method and a private method called by sanitizeNickname(). The both methods will receive a nickname parameter and return a string.
  • πŸ“Œ when the getSanitizedNick() is called with empty parameter, needs to make an error in console.

We have our case study scenario and rules! Now, let's create our service and make it happen!!!


πŸ“ Creating and coding the service:

▢️ Create the service:

❗️ Execute on our Angular project app folder! 
ng generate service services/nickmanager
Enter fullscreen mode Exit fullscreen mode

We have our service created on your services folder and the code to resolve the case study is like below.

▢️ The NicknameManager service code:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class NicknameManager {

  constructor() { }

  private sanitizeNickname(nickname: string): string {

    const nicknamePrefix = 'dev-to-';

    return nicknamePrefix + nickname.replace(' ', '').toLowerCase();
  }

  getSanitizedNick(nickname: string): string {

    if (!nickname) {
      throw new Error('getSanitizedNick() needs the nickname parameter to make the correct nick!');
    }

    return this.sanitizeNickname(nickname);
  }
}
Enter fullscreen mode Exit fullscreen mode

(Sorry guys, I don't will explain the service code because the focus is in the Test of our service!)

We made our service to resolve our problem, now let's write our beautiful Unit Test!!


πŸ“ Creating the NicknameManager Unit Test!

▢️ The problem to test:

We need to ensure that when called the getSanitizedNick() method is called with an empty parameter, an error is displayed in the console to alert the developer!

▢️ Writing our test:

✡ First: Open the nickmanager.service.spec.ts on the services folder and remove all the code and and let's do it from scratch.

✡ Second: In Jasmine we need to have our describe function to describe what we can test. It's for grouping our tests code and can receive a name and a function. Each ts file can has one spec.ts file and has a describe function.

So, let's create a describe and give it a name and the code is like below:

describe("NicknameManager Service", function() {

});
Enter fullscreen mode Exit fullscreen mode

✡ Third: The Jasmine tests specifications needs the describe and the it functions, it takes a string to be the title of the specification and takes a function too! In the title we describe the problem, I usually make it following the model below:

<!--What I'm testing--> should <!--Do Something--> when <!---The problem--->
Enter fullscreen mode Exit fullscreen mode

So our problem is showing throw error when the getSanitizedNick() is called with empty value. Based on our case study and the example of how to write the title let's do it:

And the code is like below:

describe("NicknameManager Service", function() {
  it('getSanitizedNick() should throw error when called with empty value', () => {

  });
});
Enter fullscreen mode Exit fullscreen mode

✡ Fourth: Now, we have our description and our getSanitizedNick() it function! Let's finish our test!

We need to test our getSanitizedNick() method, so we need to import our NicknameManager service and write the test.

Inside of the it we can have the expect! The expect is like: What we are expecting for the function makes!?

πŸ’‘ If you don't understanding, here is expect description by Jasmine doc:

An expectation in Jasmine is an assertion that is either true or false. A spec with all true expectations is a passing spec. A spec with one or more false expectations is a failing spec.

So, we expect the getSanitizedNick() return throw Error, so we can use the toThrowError() jasmine method and calling the getSanitizedUrlToRediret() with empty value!

Sooo the code is like below:

import { NicknameManager } from './nickname-manager.service';

describe("NicknameManager Service", function() {

  let nicknameManagerService: NicknameManager;

  it('getSanitizedNick() should throw error when called with empty value', () => {
    expect(() => {
      nicknameManagerService.getSanitizedNick('')
    }).toThrowError();
  });
});
Enter fullscreen mode Exit fullscreen mode

😁πŸ₯ΉπŸ€˜πŸΎπŸ§¨πŸ₯ΉπŸ˜πŸ€˜πŸΎ COOOOLLLLLLL 😁πŸ₯ΉπŸ€˜πŸΎπŸ§¨πŸ₯ΉπŸ˜πŸ€˜πŸΎ

We have our first Unit Test service implemented! Let's run and see the result?!

πŸ‘‡πŸ½ In your terminal run the command:
ng test --include=src/app/services/nickname-manager.service.spec.ts
Enter fullscreen mode Exit fullscreen mode

Chrome will open a new window like the image below showing the our description of your test, the it title and the success result! Take a look:

Image description

Now we have a service with a simple Unit Test implemented and making our service fully secure and with validation working correctly!


That's all guys, I hope you like it and if any questions, suggestions or other topics, please comment!

See you later ✌🏼

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .