问题描述
我将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:
app.component.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: './app.component.html',
styleUrls: ['./app.component.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 './app.component';
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]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should create the app', () => {
const app = fixture.componentInstance;
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 './app.component';
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]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should create the app', () => {
const app = fixture.componentInstance;
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-await中的角度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!