Angular Unit Testing with Jasmine
Published: 2023-08-05 07:37:00

Welcome to the world of unit testing in the angular universe! We're here to explore a developer's secret weapon – unit testing – and how it can help us craft cleaner, more robust code. 

Picture this: you're creating a really cool app, and everything looks great and works smoothly. However, unexpectedly, bugs start appearing like uninvited guests at a party. This is where unit testing steps in, acting as a safeguard to identify these bugs before they can cause any trouble in your code gathering. In this article, we're exploring the fundamental concepts of unit testing in Angular using Jasmine.

## Overview of Jasmine

Jasmine stands out as a dependable behavior-driven testing framework designed specifically for JavaScript. It operates like a nimble tester, demanding minimal resources and functioning independently. Its straightforward syntax and well-organized API simplify the testing process. The intriguing aspect? You can articulate your tests using everyday language, creating a conversational connection between your code and you. With its open-source nature, Jasmine is more than just a reliable testing tool – it's the result of a dynamic community effort. And when it comes to safeguarding your Angular projects from those elusive bugs, rest assured, Jasmine is up to the task.

## Setting Up a Basic Angular Application

Let's get started by setting up a simple Angular application. Open your terminal and navigate to the directory where you want to create the project. Run the command 

`ng new unit-test-app `

This create a new Angular application called 'unit-test-app'. Since this is a basic application, you can skip the Angular routing setup if prompted. Also, during the setup, choose the appropriate option for CSS usage. Now, you're all set to begin! Feel free to open your newly created application in a code editor of your choice.

Now, let's spice things up by adding a button component that will bring some action to our application. To do this, run the command 

`ng generate component custom-button`

In the custom-button.component.html file, add a button and give it a label "Popup" using the code below.

`<div class="button_container">
    <button>Popup</button>
</div>
`

We also want to add some basic style to our button. Add the following to your custom-button.component.css.

`
.button_container {
    width: 100vw;
    height: 100vh;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
}

button {
    padding: 15px 50px;
    border-radius: 5px;
    cursor: pointer;
    overflow: hidden;
    background-color: #007bff;
    color: white;
    border: none;
}

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5); 
    z-index: 5; 
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(5px);
  }


`

To display our custom button component, just insert the selector for the custom dialog in the app.component.html file, as shown below. Note that the overlay will come into play once we craft our dialog component.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23zfjkqyebzw9y4n5tdb.png)

We can run the command 

`ng serve`


Your application should look like the image below. Quite appealing, isn't it?🙂

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jikt1lgnnoqzsa8jm62p.png)

Moving on to the creation of our dialog component, simply execute the following command:

`ng generate component custom-dialog
`

Now, add some straightforward text into your dialog, as showcased below. 


`<div class="custom_dialog">
    <h2>Custom Dialog</h2>
    <p>I'm just a regular component, but I get conditionally displayed!</p>
    <div class="button_container">
        <button>Close</button>
    </div>
</div>`

Additionally, include some fundamental styling for the dialog, as illustrated in the provided code snippet.

`h2, p {
    color: #ffffff;
}

.custom_dialog {
    width: 40vw;
    padding: 15px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    justify-content: center;
    align-items: center;
    background-color: #007bff;
}

button {
    padding: 15px 50px;
    border-radius: 5px;
    cursor: pointer;
    overflow: hidden;
    background-color: #ffffff;
    color: 007bff;
    border: none;
}`

Navigate to your custom-button.component.ts file and establish functions to open and close the dialog, alongside a variable that manages the dialog's visibility.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bhomuq8l3f5xx3xt5gi0.png)

Also adjust your custom-button.component.html to the code below


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqe7gyx1u4sxby6fja36.png)

All that's left is to implement our close dialog function in our custom-dialog.component.ts as shown. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwrps8burpt8aclr4toa.png).

The closeDialogEvent emits an event whenever the close button is clicked on our custom dialog. To make this happen, we'll need to adjust our custom-dialog.component.html as shown.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix1gwyb4rqu9z9f0j2vx.png)

At this stage, our application is prepared.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qrjho8xheqjx6qyo54r.png)

## Writing Unit Tests with Jasmine


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbmagpbe7fnmzhiuzv3p.png)

Angular's CLI makes our job easier by generating default test files. In our case, we'll write tests for the custom button dialog in the "custom-button.component.spec.ts" file. The "component" variable (1) serves as an instance of the "CustomButtonComponent," while the "fixture" variable (2) represents the testing environment. The first function (3), executed before each test case, sets up the component for proper functioning. The second function (4) includes "fixture.detectChanges()" to trigger the component's change detection cycle. By default, a base test (5) is automatically included.

The "it" function requires two parameters: a descriptive string for the test case and a callback function containing the test logic. Inside the callback, the "expect" function takes the center stage. This function acts as an assertion for the test case. In the first test, we verify that the "CustomButton" component is "toBeTruthy." Here, "toBeTruthy" serves as a Jasmine matcher, a tool that assesses whether the tested value isn't false, null, undefined, 0, NaN, or an empty string. This test essentially checks if our component exists and is valid.

In our testing process, we'll verify whether the dialog open function is activated upon clicking the "Open Dialog" button, and similarly, whether the close dialog function is activated upon clicking the "Close Dialog" button. To achieve this, we'll introduce a new test function, as depicted below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8gbhms2w2uv3nokbsh4.png)

This first test case above checks whether the openDialog() function of the component correctly changes the value of isDialogOpen to true when the "Open Dialog" button is clicked. If the expectation holds true, the test case will pass; otherwise, it will fail. The second test case on the other hand check if the closeDialog() function is called correctly when the dialog gets closed.

After you're done setting up your tests, it's time to see how they perform. Just type `ng test` in your terminal, and the Jasmine tests will start running. You'll see the results in the console. If everything goes well and your code passes the tests, you'll see a message saying everything is successful. But if something doesn't work as expected, don't worry – you'll get information about what's not working and where in your code. This helps you catch and fix any issues before they become bigger problems.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9idjha8t26o078jm748.png)

Hooray, you're a bug-busting champion! Your tests have triumphed, and success is on your side. Great job!