Home  >  Angular

Angular TestBed compileComponents()

By Arvind Rai, April 11, 2022
On this page we will learn using TestBed.compileComponents() method in Angular test.
1. Angular TestBed configures and initializes environment for unit testing. The compileComponents() is the method of TestBed class. The compileComponents() is used to compile the components.
compileComponents(): Promise<any> 
If the source code is in memory, then calling compileComponents() is not necessary but when components use templateUrl and styleUrls to load external files then compiler has to read files and that is an asynchronous operation. In this case we need to call compileComponents().

2. Calling compileComponents() is needed only when our component is using templateUrl and/or styleUrls.
@Component({
  selector: 'app-person',
  templateUrl: './person.component.html',
  styleUrls:  ['./person.component.css']
}) 
The above code needs to read external files (html and css) during component compilation. This is not the problem when we run test using ng test. If we only run test with CLI ng test command then we can ignore compileComponents() because the CLI compiles the application before running the tests.
The compileComponents() is called as following.
beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [ PersonComponent ],
  }).compileComponents();
}); 
The compileComponents() is called within an asynchronous test function.




3. Suppose we are not running our tests using CLI commands and we have not called compileComponents() method. Our code is as below.
beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [ PersonComponent ],
  }); // missing call to compileComponents()
}); 
Suppose we are running our test using Plunker. Then an error will be thrown.
"Error: This test module uses the component PersonComponent
which is using a "templateUrl" or "styleUrls", but they were never compiled.
Please call "TestBed.compileComponents" before your test." 
The solution is simple, just call compileComponents() and error will be fixed.

4. We should create component only after its compilations. Hence we must call createComponent() only after compileComponents(). The compileComponents() is asynchronous code whereas createComponent() is synchronous code. We can write our code using them as following.
beforeEach(async () => {
  // Calling compileComponents() is asynchronous code
  await TestBed.configureTestingModule({
    declarations: [ PersonComponent ],
  }).compileComponents();
  // Creating Component is synchronous code
  fixture = TestBed.createComponent(PersonComponent);
  component = fixture.componentInstance;
}); 

5. Calling compileComponents() is harmless. We can call compileComponents() even if it is not required. The component test file generated by the CLI calls compileComponents() even though it is never required when running ng test

Complete Example

1. Technologies Used
Find the technologies being used in our example.
1. Angular 13.1.0
2. Node.js 12.20.0

2. Test Case
person.component.spec.ts
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { PersonComponent } from './person.component';

describe('PersonComponent', () => {
  let component: PersonComponent;
  let fixture: ComponentFixture<PersonComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [PersonComponent],
    }).compileComponents();
    fixture = TestBed.createComponent(PersonComponent);
    component = fixture.componentInstance;
  });
  it('should match H1 text', fakeAsync(() => {
    const h1 = fixture.debugElement.nativeElement.querySelector('h1');
    fixture.detectChanges();
    expect(component.message).toBe(h1.textContent);
  }));
}); 

3. Find our application code.
person.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-person',
  templateUrl: './person.component.html',
  styleUrls: ['./person.component.css']
})
export class PersonComponent {
  message = "Hello World!";
} 
person.component.html
<h1>{{message}}</h1> 
person.component.css
h1 {
    color: blue;
  } 

Running Test Case

Here we are using ng test to run test cases. Find the print screen of the output.
Angular TestBed compileComponents()

Reference

Component testing scenarios

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI










©2022 concretepage.com | Privacy Policy | Contact Us