Unit Testing in Angular: The Basics and a Quick Tutorial

Oliver Moradov

What Is Unit Testing in Angular?

Angular is an application design framework and development platform for creating complex, high performance single page applications.

Angular unit tests help you test a specific unit of Angular code in isolation. Angular unit tests isolate parts of your code to reveal problems like bad logic, coding errors, or malfunctioning features. 

Unit testing can be difficult to achieve for complex projects with poor separation of concerns. However, Angular allows you to write code in such a way that it can be easy to individually test each piece of functionality in your application. If you plan for unit testing in advance and follow Angular coding best practices, it should be straightforward to add unit tests to your applications.

In this article:

Why Should You Unit Test Angular Apps?

Angular unit tests allow you to test your application for coding errors and unexpected user behavior. Testing all possible behaviors can be tedious and inefficient, but generating tests for each coupling block in your application will help identify problems with each block.

One of the easiest ways to test the strength of a block is to create a test for each block. You should do this proactively, and not wait for a bug to surface in production. Create unit tests for blocks (components, services, etc.) to easily detect bugs and fix them earlier in the development process.

Basics of Angular Component Testing

Angular component testing involves checking the performance and quality of application components. You can perform Angular component tests manually by running the application to see if the components behave as expected. However, manual testing is time-consuming and impractical for large, complex web applications. You’ll most likely need to find a better way to test Angular components. 

Angular projects using the Angular CLI come with Jasmine and Karma to simplify and automate the testing process. Jasmine is a behavior-based testing framework you can use to write unit tests. You can then run the tests on Karma to verify if individual application parts are functioning correctly. The unit tests pass if the code functions correctly and fail if it contains a bug.

The test files should use the name.component.spec.ts naming convention. Keeping them with the other files associated with the same component is best. If you built your Angular app using the Angular CLI, you might have seen the app.component.spec.ts file – this file has unit tests for the core AppComponent. When you run tests with the Angular CLI, you run all the unit tests in the *.spec.ts files.

You can use the ng test command in the terminal to run tests with the Angular CLI. It will trigger Karma to open the default browser to run the tests you wrote using Jasmine and display the test outcomes.

Here are some of the basic functions in Jasmine:

  • describe(string, function) – takes a title and function containing one or multiple specs. It is also called a test suite.
  • it(string, function) – takes a title and function that contains one or multiple expectations. It is also called specs.
  • expect(actual) – takes a value known as an actual. Typically, you use expect functions alongside matcher functions. They work together to return boolean values depicting a spec’s passing or failing.
  • Matcher – takes a value representing the expected value. Matcher function are chained to expect functions. Examples of matchers include toBeTruthy(), toContain(), and toEqual().

Related content: Read our guide to unit testing best practices

Quick Tutorial: How to Code an Angular Unit Test

An Angular unit test is based on a describe container, which has several different blocks such as it, beforeEach, and xit. The beforeEach block always runs first. Other blocks do not depend on each other and may run in any order. Almost all unit tests use two utilities called TestBed and async.

The beforeEach block declares an application component that should run in the testing environment. Here is an example of a beforeEach block. Note that the compileComponents() function might not be needed if you are using webpack.

beforeEach(async(() => {
   TestBed.configureTestingModule({
      declarations: [
         MyComponent
      ],
   }).compileComponents();
}));

A first step in a unit test is to verify that an instance of the application component is successfully created. See the code below—the property fixture.debugElement.componentInstance generates an instance of your component. The code tests whether the component is created using the assertion toBeTruthy :

it('component should be created', async(() => {
    const fixture = TestBed.createComponent(MyComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
}));

Now, let’s write another code block that shows whether we have access to the properties of the component. The following test checks if the title that would appear in the browser when the component is rendered is really the correct title. Of course you would have to switch my-title for the actual title defined in the component.

it(`component should have title 'my-title'`, async(() => {
     const fixture = TestBed.createComponent(MyComponent);
     const app = fixture.debugElement.componentInstance;
     expect(app.title).toEqual('my-title');
}));

Finally, we can inspect DOM elements created by the component. Let’s check the <h1> HTML tag generated by the component. We’ll use the detectChanges() function to simulate running in a browser environment. The fixture.debugElement.nativeElement property will give us access to an actual on-page DOM element.

it('component should render 'Welcome to My App' in h1 tag', async(() => {
   const fixture = TestBed.createComponent(MyComponent);
   fixture.detectChanges();
   const compiled = fixture.debugElement.nativeElement;
 expect(compiled.querySelector('h1').textContent).toContain('Welcome to My App!');
}));

This is a simple demonstration of how a specs.ts file can help you load an Angular application component, run it in a testing environment, and verify different aspects of the component in a simulated browser environment.

Security Unit Testing in Angular with Bright Security

Bright is a developer-first Dynamic Application Security Testing (DAST) scanner, the first of its kind to integrate into unit testing, revolutionizing the ability to shift security testing even further left. You can now start to test every component / function at the speed of unit tests, baking security testing across development and CI/CD pipelines to minimize security and technical debt, by scanning early and often, spearheaded by developers. With NO false positives, start trusting your scanner when testing your applications and APIs (SOAP, REST, GraphQL), built for modern technologies and architectures. Sign up now for a free account and read our docs to learn more.

Secure your app with every build

Sign up for a FREE Bright account.
Related Articles
Categories
Bright Screenshot

Secure your app with every build

  • Easily and quickly find & fix security bugs

  • Automate it in your build pipeline

  • No false positives

  • Scan any target: web apps & APIs

Join our workshop: JavaScript Global Summit’22