Angular Component Testing: A Detailed How-To With Examples

In this post, we'll provide you with an introductory guide to Angular component testing. We'll discuss the importance of testing…

By Testim,

In this post, we’ll provide you with an introductory guide to Angular component testing. We’ll discuss the importance of testing and the tools used and provide examples on how to approach testing your components.

What Is Angular Component Testing?

Angular component testing means to check the quality and performance of your components. Angular component testing can be done manually by running the application yourself and checking to see if a component’s behavior is working as expected. But as web applications get larger and more complex, manually testing your components, consequently, becomes more time-consuming. In reality, this isn’t practical, so ultimately we’ll need to find a better solution for Angular component testing.

Luckily for us, an Angular project created using the Angular CLI comes with Karma and Jasmine to make testing simple by automating the process. Jasmine is a behavior development testing framework. Unit tests are written using Jasmine and are run to see if individual parts of an application are working correctly. As a result, unit tests will either pass or fail depending on if the code is working correctly or has a bug. Angular uses Karma as the test runner for the project’s unit tests.

How Do We Start Testing Our Components?

Test files should follow the name.component.spec.ts naming convention and should be located alongside the component’s other files. If you used the Angular CLI to create your Angular application, you might have noticed the app.component.spec.ts file. This file contains unit tests for the main AppComponent. When running tests using the Angular CLI, all unit tests in files with the *.spec.ts extension will run.

To run your tests using the Angular CLI, you use the ng test command in your terminal. As a result, Karma will open up the default browser and run all the tests written with the aid of Jasmine and will display the outcome of those tests.

Learning the Basics of Angular Component Testing

To learn the basics of Angular component testing, we’ll be using a brand new application created with the Angular CLI, then we’ll examine app.compoment.spec.ts in detail. To start, create a new Angular application by typing ng new angular-component-testing from your terminal. Be sure to select “no” when asked to include Angular routing. If you run ng test in your new application’s directory, your default browser should open and display the outcome of the tests for the AppComponent.

But before we examine app.component.spec.ts in detail, let’s learn some Jasmine terminology.

  • describe(string, function) functions take a title and a function containing one or more specs and are also known as a suite or test suite.
  • it(string, function) functions take a title and a function containing one or more expectations and are also known as specs.
  • expect(actual) functions take a value, called an actual. An expect function is typically used alongside a matcher function. Together they return a boolean value that depicts the passing or failing of a spec.
  • Matcher functions take a value that represents the expected value. A matcher function is chained alongside an expect function. Together they return a boolean value that depicts the passing or failing of a spec. Some examples of matchers are toBeTruthy(), toEqual(), and toContain().

Now that we have some basic terminology down, let’s take a look at app.component.spec.ts. Below is the original generated code for app.component.spec.ts with added comments for easy reference.

A Closer Look Into App.component.spec.ts

  1. In order to test our Angular component’s functionality, we need to import some Angular testing tools, which we’ll use alongside Jasmine. TestBed is used to configure and initialize the environment unit tests.
  2. The describe code block represents the test suite for AppComponent. It contains specs and additional code that’s used for testing AppComponent.
  3. beforeEach is a global function in Jasmine that runs some setup code before each spec in the test suite. In this test suite, beforeEach is used to create a testing module using the TestBed object and declares any components that would be used in this testing module. This code creates a version of your Angular application that can be used alongside Jasmine to test component functionality.
  4. This is the first spec of the test suite and tests to see if the component compiles correctly. The TestBed.createComponent() method is used to create an instance of the AppComponent. The spec then uses expect and matcher functions to see if the component produces the expected behavior. As a result, the spec will either pass or fail. In this case, the expectation is that the AppComponent is defined.
  5. This spec tests to see if the AppComponent has a local variable called title with the hard coded value of “angular-component-testing.” The spec prevents any unwanted changes or deletions of the variable title in the AppComponent.
  6. This spec tests to see if the page’s welcome text reads correctly. The spec introduces the detectChanges() method, which binds the data to the component instance. Then, using the fixture.debugElement.nativeElement property, we’re able to check if the compiled component code contains an h1 HTML element with text that reads “Welcome to angular-component-testing!” The spec expects the welcome message to be placed inside of an h1 HTML element that reads “Welcome to angular-component-testing!”

Creating Our Own Unit Tests

Now that we know a few Angular component testing basics, let’s create a component where we eventually will write our own unit tests. First, we’ll create a TitleComponent. TitleComponent has a text input and a button used to change the title property in the parent AppComponent with an EventEmitter. Place the code below at src/app/title/title.component.ts.

There are two things to note with the code above:

  1. @Input named message, which will display a message above the text input.
  2. @Output, which will emit an event to replace the value of title in the parent AppComponent, therefore changing the welcome message.

Later we’ll be writing unit tests to make sure that the component is receiving an input correctly as well as outputting data correctly.

However, for TitleComponent to work correctly, we also need to update the app.component.ts, app.component.html, and app.module.ts files.

Firstly, in app.component.ts, we added a method that changes the title property for when the TitleComponent emits a new title.

We’ve added the TitleComponent in the app.component.html file. We also included a value for the message attribute and provided a function for the changeTitleEvent output.

Lastly, we declared our new component in our app.module.ts in order to use the TitleComponent in our application.

Keep Your Tests Updated

One major challenge with Angular component testing is keeping your unit tests updated. Often, with the addition of new components working together, unit tests will fail or no longer be valid. One example of this is our unit tests for AppComponent. Because our new TitleComponent isn’t declared in our test for AppComponent, you’ll notice that the “Application should create the app” spec is failing. To fix this, we need to import the TitleComponent and include it in the test module’s declarations.

Now that you’ve got your TitleComponent up and running, let’s start writing some tests.

Start out by creating a title.component.spec.ts file that lives in the same folder as the title.component.ts file, with the following code.

Our Test Suite in Detail

  1. We start out by creating a test suite for our TitleComponent. Within the describe() function, we create a ComponentFixture of the TitleComponent. ComponentFixture provides methods and properties that help test the functionality of a component.
  2. We use the beforeEach function to create a test module that sets up the environment for testing our component.
  3. We use another beforeEach function to create an instance of the TitleComponent and call the detectChanges() method to ensure that the component data is up to date.
  4. This is our first spec, which tests to see if the component compiles correctly.

Although we have a unit test that tests to see if the TitleComponent compiles correctly, unfortunately it’s not enough. In reality, we should also test that the component implements its @Input and @Output correctly.

Testing the @Input of a Component

In order to test that @Input works correctly, we’ll write a spec that checks to see if the message property is equal to what we expect it to be.

The Spec in Detail

  1. We set the value of the component’s message property to “Enter a new title.”
  2. Update the component’s data.
  3. Create a variable reference to the compiled component code.
  4. Check if the text in the compiled component’s paragraph element is equal to the value of the component’s message property.

Testing the @Output of a Component

Now we’ll need to test that the TitleComponent implements @Output correctly. We’ll write a spec that checks if the component emits the correct value when changeTitleEvent is emitted.

The Spec in Detail

  1. Use the spyOn function to effectively “spy” on the emit method of component.changeTitleEvent object.
  2. Change the value of the component’s text input.
  3. Simulate the button click of the comment.
  4. Check to see if component.changeTitleEvent.emit emits the value of inputText.

There you have it—the TitleComponent unit tests are now complete.

Summing It All Up

Angular component testing is an essential part of software development. It helps maintain the quality of code by running automated tests on your application’s specifications. Overall, Angular component testing saves time, helps find bugs early, and inspires confidence in your applications code.

This post was written by Jonathan Dauz. Jon is a front-end engineer who loves to build fun, innovative, unique websites and web applications. Most of his work has been focused on the front-end, but that hasn’t stopped him from working with back-end technologies. Jon has experience working with a wide array of languages, tools, and frameworks, such as Angular, React, Vue, PixiJS, and Node.

What to read next

Angular Testing Tutorial: What You Need and How to Start

Angular Integration Testing: A Practical, Introductory How-To

Testim's latest articles, right in your inbox.

From our latest feature releases, to the way it impacts the businesses of our clients, follow the evolution of our product

Blog Subscribe