Testing Angular components

Over the course of using the Angular CLIwe have generated multiple components and services. Take a pause and review the files and folder structure. You will notice that, for each component and service, a .spec.ts file has been generated.

Eureka moment! The Angular CLI has been generating the required shell test scripts for the respective components and services. Let's do a quick hands-on exercise here. Let's generate a component named auto-list:

ng g component auto-list

The Angular CLI autogenerates the required files and also makes entries in the required files (AppModule, Angular.json, and so on).

The following screenshot depicts the test specs generated by the CLI:

Take a closer look at the files that were generated. You will see the following files generated for the component:

  • auto-list.component.html
  • auto-list.component.spec.ts
  • auto-list.component.ts
  • auto-list.component.scss

We are interested in the spec file generated by the Angular CLI. A spec file is the test script that was generated for the corresponding component. The spec file will have the basic required modules imported, along with the Component class. The spec file will also have some basic test specs already written, which can be used as a starting point or, alternatively, as our motivation.

Let's take a closer look at the code generated in the spec file:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AutoListComponent } from './auto-list.component';

In the preceding code, you will notice that the required modules are imported from the Angular testing core. This is certainly not the final list of modules we will work with but just basic starter ones. You will also notice that the newly created component, AutoListComponent, is also imported into our spec file, which means that we can create an instance of our class inside the spec file and start mocking the objects for testing purposes. Pretty cool? Moving on to the lines of code, we can see the following:

describe('AutoListComponent', () => {
let component: AutoListComponent;
let fixture: ComponentFixture<AutoListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AutoListComponent]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AutoListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

In the preceding code, you will notice some key points. There is a describe statement, which is used for grouping related test specs together. We will create test specs inside the describe function. There are two beforeEach methods defined in the spec file.

The first beforeEach method is an async promise, which will set up our TestBed, which means everything declared in it has to be resolved before moving on; otherwise, our tests won't work. The second beforeEach method will create an instance of our AutoList component for testing. You will notice the call to fixture.detectChanges(), which forces Angular's change detection to run and affect the elements in the test beforehand.

Now, it's time to understand the actual test spec, which is generated in the spec file:

it('should create', () => {
expect(component).toBeTruthy();
});

As we mentioned earlier, the Jasmine test specs are written inside the it statement, which, in this case, is just a simple assert to check whether the component exists and is true, using the toBeTruthy matcher.

That's all about our spec file. The joy lies in seeing it work. Let's just run the default tests that Angular has generated for us. To run the tests written inside the Angular application, we use the ng test command on the command-line interface:

ng test

If you see a new window being opened, don't panic. You will notice that a new browser window is opened by the Karma runner to execute the tests, and the test execution report is generated. The following screenshot displays the report that was generated for our test spec for the component:

So, our test passed. Now, let's modify the script a bit. We will create a variable called title in our component and assign a value. In our test spec, we will verify whether the value matches or not. It's a straightforward use case and, trust me, it's also the most frequent use case you will implement in your applications. Let's open the app.component.spec.ts file and make the changes in the test script: 

it(`should have as title 'testing-app'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('AutoStop');
});

In the preceding code, we are writing a test spec and, using TestBed, we are creating a fixture element of AppComponent. Using the fixture element's debugElement interface, we are getting the componentInstance property. Next, we are writing an expect statement to assert if the value of the title variable is equal to AutoStop. That was neat. Let's try and write one more test spec. The use case we will address is as follows: we have an H1 element and we want to assert it if the value inside the H1 tag is equal to Welcome to Autostop. The following is the relevant sample code:

it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to
AutoStop');
});

In the preceding code, we are asserting if the textContent of the h1 element contains the text Welcome to AutoStop. Notice that, in previous test specs, we used the componentInstance interface and that, in this test spec, we are using the nativeElement property. Again, run the tests using the ng test command. The following screenshot shows the test report that was generated:

So far, we have had an overview of the Jasmine and Karma frameworks, and also learned how to run our test scripts. We also learned about the default spec files that Angular generates for us and learned how to modify the test specs.

In the upcoming sections, we will learn how to write test specs and scripts to test Angular built-in directives, services, routes, and much more.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.236.62