【发布时间】:2020-07-02 16:12:01
【问题描述】:
这是我的 Angular 代码,功能运行良好,但测试用例失败。请告诉我我在代码中做错了什么? 我得到的错误
HeadlessChrome 83.0.4103 (Windows 10.0.0) AboutComponent 应该创建 FAILED TypeError:无法读取未定义的属性“getAboutInfo” 在 ** 在 AboutComponent.ngOnInit (http://localhost:9876/karma_webpack/src/app/about/about.component.ts:44:28) 在 callHook (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3937:1) 在 callHooks (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3901:1) 在 executeInitAndCheckHooks (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3842:1) 在 refreshView (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11795:1) 在 renderComponentOrTemplate (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11903:1) 在 tickRootContext (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:13379:1) 在 detectChangesInRootView (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:13413:1) 在 RootViewRef.detectChanges (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:15093:22) 在 ComponentFixture._tick (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/testing.js:323:1)
import { async, ComponentFixture, TestBed} from '@angular/core/testing';
import { AboutComponent } from './about.component';
import { AboutService } from './about.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { Observable, of } from 'rxjs';
import { I18nService } from 'src/utils/i18n.service';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { AppModule } from './../app.module';
describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;
let dialogSpy: jasmine.Spy;
let app: any;
const mockDialogRef = {
close: jasmine.createSpy('close')
};
let service: any;
const data = '20/04/2019';
let getAboutInfoSpy: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AboutComponent],
imports: [HttpClientTestingModule , AppModule],
providers: [{ provide: AboutService, useValue: service },
I18nService,
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: mockDialogRef}]
}).compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(AboutComponent);
component = fixture.componentInstance;
await fixture.whenStable();
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('infoList should be empty array', () => {
expect(app['dataList'].length).toBe(0);
});
it('when OnInit invoked through service data will return to infoList ', async(() => {
service = fixture.debugElement.injector.get(AboutService);
spyOn(service, 'getAboutInfo').and.returnValue(of(data));
app.ngOnInit();
expect(app['dataList'].length).toBe(3);
}));
it('onCancel should close the dialog', async( () => {
component.closePopup();
expect(mockDialogRef.close).toHaveBeenCalled();
}));
});
import { Component, OnInit, Inject } from '@angular/core';
import { AboutService } from './about.service';
import { Subscription } from 'rxjs';
import { MatDialogRef} from '@angular/material/dialog';
import { I18nService } from 'src/utils/i18n.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
private aboutServiceSubscription: Subscription;
dataList: any;
locales: any = {};
translator: any;
constructor(
private dialogRef: MatDialogRef<AboutComponent>,
public aboutService: AboutService,
private i18Service: I18nService) {}
ngOnInit() {
this.translator = this.i18Service.getTranslator();
this.translator.translateObject.subscribe((item: any) => {
this.locales = item;
});
this.aboutServiceSubscription = this.aboutService.getAboutInfo().subscribe((data: any) => {
if (data) {
data = data.split('/');
this.dataList = data;
}
});
}
/**
* Closes the poup
* @memberof AboutComponent
*/
closePopup() {
this.dialogRef.close();
}
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AboutService {
constructor(private http: HttpClient) {
}
getAboutInfo() {
return this.http.get('/assets/aboutInfo.txt', {responseType: 'text'})
}
}
【问题讨论】:
-
providers: [{ provide: AboutService, useValue: service },service 变量的值 -
我该怎么做?
-
service = <something>。如service = jasmine.createObjectSpy('AboutService', ['getAboutInfo'])。但是,由于服务是providedIn: 'root',您根本不必这样做。您应该能够删除该提供程序行,然后使用TestBed.inject(AboutService)来获取注入到您的组件中的服务。
标签: javascript angular typescript unit-testing karma-jasmine