Angular Test tick()
May 05, 2022
On this page we will learn to use tick()
function in our Angular test. The tick()
function simulates the asynchronous passage of time for the timers in the fakeAsync
zone in Angular test.
Find the
tick()
function from Angular doc.
tick(millis: number = 0, tickOptions: { processNewMacroTasksSynchronously: boolean; } = { processNewMacroTasksSynchronously: true }): void
millis : Time in milliseconds to advance the virtual timer. It is optional and default value is 0.
tickOptions : Optional. Default is
{ processNewMacroTasksSynchronously: true }
Find the sample use of
tick()
function.
it('test with setTimeout', fakeAsync(() => { let flag = false; setTimeout(() => { flag = true; }, 100); expect(flag).toBe(false); tick(100); expect(flag).toBe(true); }));
Technologies Used
Find the technologies being used in our example.1. Angular 13.1.0
2. Node.js 12.20.0
3. Jasmine 3.10
4. Karma 6.3
Using processNewMacroTasksSynchronously
The default value of ‘processNewMacroTasksSynchronously’ is true in tick options. Find the example in which we have a nestedsetTimeout
function, this will be executed synchronously for the default value (true) of ‘processNewMacroTasksSynchronously’.
it ('test with nested setTimeout', fakeAsync(() => { let flag = false; function funWithNestedTimeout() { setTimeout(() => { flag = true; }); }; setTimeout(funWithNestedTimeout); tick(); expect(flag).toBe(true); }));
Now suppose we have the tick option as following.
{processNewMacroTasksSynchronously: false}
tick
function call, the nested setTimeout
function will not execute.
it ('test with nested setTimeout', fakeAsync(() => { let flag = false; function funWithNestedTimeout() { setTimeout(() => { flag = true; }); }; setTimeout(funWithNestedTimeout); tick(0, {processNewMacroTasksSynchronously: false}); expect(flag).toBe(false); }));
Complete Example
app.component.spec.tsimport { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { AppComponent } from './app.component'; import { of, throwError } from 'rxjs'; import { EmployeeService } from './employee.service'; describe('#AppComponent', () => { let component: AppComponent; let fixture: ComponentFixture<AppComponent>; let getEmpByIdSpy: any; const testEmp = { id: '101', name: 'Mohan' }; beforeEach(async () => { const empServiceSpy = jasmine.createSpyObj('EmployeeService', ['getEmpById']); getEmpByIdSpy = empServiceSpy.getEmpById.and.returnValue(of(testEmp)); await TestBed.configureTestingModule({ declarations: [AppComponent], providers: [{ provide: EmployeeService, useValue: empServiceSpy }] }).compileComponents(); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; }); it('test with setTimeout', fakeAsync(() => { let flag = false; setTimeout(() => { flag = true; }, 100); expect(flag).toBe(false); tick(100); expect(flag).toBe(true); })); it('test with nested setTimeout', fakeAsync(() => { let flag = false; function funWithNestedTimeout() { setTimeout(() => { flag = true; }); }; setTimeout(funWithNestedTimeout); tick(); expect(flag).toBe(true); })); it('should display error when EmployeeService fails', fakeAsync(() => { getEmpByIdSpy.and.returnValue(throwError(() => new Error('EmployeeService test failure'))); fixture.detectChanges(); // Initializes the component tick(); // flush the component's setTimeout() fixture.detectChanges(); // Updates the component const error = fixture.nativeElement.querySelector('.error'); expect(error.textContent) .withContext('should display error') .toContain('EmployeeService test failure'); })); });
