Learning and Implementing Unit Testing in an Angular Project
Tags: testing, angular, jasmine, tutorial
Published: 2023-01-12 20:27:43

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
```

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

▶️ **The NicknameManager service code:**

```typescript
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);
  }
}
```
(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: 

```typescript
describe("NicknameManager Service", function() {
    
});
```

**✵ 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:

```html
<!--What I'm testing--> should <!--Do Something--> when <!---The problem--->
```

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: 

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

  });
});
```

**✵ 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:

```typescript
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();
  });
});
```

😁🥹🤘🏾🧨🥹😁🤘🏾 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
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjl3rfnxefm7znffblw7.png)

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 ✌🏼