我将Angular 9+与业力测试运行程序和茉莉花测试框架一起用于单元测试.
I am using Angular 9+ with karma test runner and jasmine test framework for unit tests.
我只想对具有依赖项注入的 app组件 进行单元测试:
I wanted to unit test only app component which has a dependency injection:
appponent.ts
import { Component, EmbeddedViewRef } from '@angular/core'; import * as moment from 'moment-timezone'; import { OtherServiceService } from './other-service.service'; import { Location } from '@angular/common'; @Component({ selector: 'app-root', templateUrl: './appponent.html', styleUrls: ['./appponent.css'] }) export class AppComponent { constructor(private sampleService: OtherService, private location: Location){} async func(){ await this.sampleService.func2().toPromise(); console.log('Async call completed'); this.location.go('/index.html'); } }other-service.service.ts
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class OtherServiceService { constructor(private http: HttpClient) { } func2(){ return this.http.post('' , null); } }到目前为止我已经尝试过的单元测试:
The unit test i have tried so far:
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async, fakeAsync, tick } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { AppComponent } from './appponent'; import { OtherServiceService } from './other-service.service'; const locationStub = { go: jasmine.createSpy('go') } describe('AppComponent', () => { let otherServiceStub; let fixture, component; beforeEach(async(() => { otherServiceStub = jasmine.createSpyObj(['func2']); TestBed.configureTestingModule({ imports: [ RouterTestingModule ], declarations: [ AppComponent ], providers: [ {provide: OtherServiceService , useValue: otherServiceStub}, {provide: Location, useValue: locationStub} ], schemas: [NO_ERRORS_SCHEMA] })pileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(AppComponent); component = fixtureponentInstance; }); it('should create the app', () => { const app = fixtureponentInstance; expect(app).toBeTruthy(); }); it('should check for correct logs',fakeAsync(() => { otherServiceStub.func2.and.returnValue(of('Garbage')); const location = fixture.debugElement.injector.get(Location); let spyObj = spyOn(console,'log'); component.func(); tick(); expect(spyObj).toHaveBeenCalledWith('Async call completed'); expect(location.go).toHaveBeenCalledWith('/index.html'); })); });在运行ng test --code-coverage时,它始终显示错误 预期的间谍已被调用为:['/index.html'],但从未被调用..
On running ng test --code-coverage, it always shows error Expected spy go to have been called with: [ '/index.html' ] but it was never called..
在覆盖率报告中,该行显示为被覆盖(this.location.go),但是测试失败,我似乎无法理解为什么.我还从此寻求帮助,但没有成功.
On the coverage report, it shows the line as covered (this.location.go) , but the test fails, and I can't seem to understand why. I have also taken help from this, but to no success.
UPDATE 1.0 :
UPDATE 1.0:
我已经尝试过@ AliF50的建议:
I have tried as suggested by @AliF50:
async func(){ await this.sampleService.func2().toPromise(); console.log('Async call completed'); this.location.go('/index.html'); console.log('After location go in component'); } it('should check for correct logs',fakeAsync(() => { otherServiceStub.func2.and.returnValue(of('Garbage')); let spyObj = spyOn(console,'log'); component.func(); tick(); const location = fixture.debugElement.injector.get(Location); expect(spyObj).toHaveBeenCalledWith('Async call completed'); console.log('Before location go in test'); expect(location.go).toHaveBeenCalledWith('/index.html'); console.log('After location go in test'); }));但是,令我惊讶的是,即使控制台显示有被覆盖的行,控制台日志中的都没有被打印.
But to my suprise none of the console logs are being printed, even though it shows lines as covered.
UPDATE 2.0 :
UPDATE 2.0:
如@ AliF50所建议:
As suggested by @AliF50:
it('should check for correct logs',fakeAsync(() => { otherServiceStub.func2.and.returnValue(of('Garbage')); let spyObj = spyOn(console,'log').and.callThrough(); component.func(); tick(); const location = fixture.debugElement.injector.get(Location); expect(spyObj).toHaveBeenCalledWith('Async call completed'); console.log('Before location go in test'); expect(location.go).toHaveBeenCalledWith('/index.html'); console.log('After location go in test'); }));所有控制台日志正在打印,但错误仍然存在.
All the console logs are being printed, but the error still remains.
UPDATE 3.0 :任何人都好运吗?这仍然是一个悬而未决的问题
UPDATE 4.0 :感谢安德烈(Andrei).问题已解决.
推荐答案最后,经过了这么多时间,再加上 @Andrei 的贡献,我才能够提出以下问题的答案:
Finally after so much time, and @Andrei's contribution, I was able to come up with the answer to this question:
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TestBed, async, fakeAsync, tick } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { of } from 'rxjs'; import { AppComponent } from './appponent'; import { OtherServiceService } from './other-service.service'; import { Location } from '@angular/common'; fdescribe('AppComponent', () => { let otherServiceStub; let fixture, component; beforeEach(async(() => { otherServiceStub = jasmine.createSpyObj(['func2']); TestBed.configureTestingModule({ imports: [ RouterTestingModule ], declarations: [ AppComponent ], providers: [ {provide: OtherServiceService , useValue: otherServiceStub}, Location ], schemas: [NO_ERRORS_SCHEMA] })pileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(AppComponent); component = fixtureponentInstance; }); it('should create the app', () => { const app = fixtureponentInstance; expect(app).toBeTruthy(); }); it('should check for correct logs',async () => { otherServiceStub.func2.and.returnValue(of('Garbage')); let locationObj = TestBed.inject(Location); let spyObj = spyOn(locationObj,'go'); await component.func(); expect(spyObj).toHaveBeenCalledWith('/index.html'); }); });单元测试正在通过,所有行均显示为已覆盖.
The Unit test is passing now with all the lines are being shown as covered.
更多推荐
单元测试位置在async
发布评论