Angular TestBed compileComponents()
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>
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'] })
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(); });
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() });
"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."
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 UsedFind 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!"; }
<h1>{{message}}</h1>
h1 { color: blue; }
Running Test Case
Here we are using ng test to run test cases. Find the print screen of the output.