angular - 如何使用 Jasmine 处理对 Angular 单元测试的依赖注入?
问题描述
我第一次尝试在 Angular 中实现单元测试,我正在使用Jasmine。我来自 Java\Spring 并使用 Spring 框架自动将所有依赖项注入到我的测试中,但我不知道如何使用 Angular Unit Test 和Jasmine来做到这一点。
我试图更好地解释我必须做什么。
1)我有这个PeopleListComponent组件类:
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
import { EventService } from '../event.service';
import interactionPlugin, { Draggable } from '@fullcalendar/interaction';
interface WorkShiftTypes {
name: string;
value: string;
}
@Component({
selector: 'app-people-list',
templateUrl: './people-list.component.html',
styleUrls: ['./people-list.component.css']
})
export class PeopleListComponent implements OnInit {
people: any[];
//cities: City[];
workShiftTypes: WorkShiftTypes[];
selectedShift: WorkShiftTypes;
@ViewChild('draggable_people') draggablePeopleExternalElement: ElementRef;
constructor(private eventService: EventService) { }
ngOnInit(): void {
this.eventService.getPeople().then(people => {this.people = people;});
this.selectedShift = {name: 'Mattina', value: 'Mattina'};
this.workShiftTypes = [
{name: 'Mattina', value: 'Mattina'},
{name: 'Pomeriggio', value: 'Pomeriggio'},
{name: 'Notte', value: 'Notte'},
{name: 'Custom', value: 'Custom'}
];
}
ngAfterViewInit() {
console.log("PEOPLE LIST ngAfterViewInit() START !!!")
var self = this
new Draggable(this.draggablePeopleExternalElement.nativeElement, {
itemSelector: '.fc-event',
eventData: function(eventEl) {
console.log("DRAG !!!");
//console.log("SELECTED SHIFT: " + self.selectedShift.value);
return {
title: eventEl.innerText,
startTime: "17:00",
duration: { hours: 8 }
};
}
});
}
createEventObject() {
return 1;
}
}
如您所见,该组件包含这个非常简约的方法createEventObject():
createEventObject() { 返回 1; }
目前只返回值1(我希望尽可能简单地尝试我的单元测试,然后我将实现真正的用例)。
好的,所以我创建了这个people-list-spec.ts文件,该文件将包含上一个方法的单元测试:
import { PeopleListComponent } from "./people-list.component"
import { EventService } from '../event.service';
describe('people-list', () => {
let eventService = new EventService();
let component = new PeopleListComponent(eventService);
it('createEventObject() return 1', () => {
})
})
好的,所以我要做的是获取一个PeopleListComponent实例,对其调用createEventObject()并检查返回值是否为1以断言单元测试成功。
在这里我有以下问题:PeopleListComponent构造函数采用EventService参数。好的...我可以构建它并传递它,但是EventService构造函数采用HttpClient参数。
在我的项目中,所有这些依赖注入都是由 Angular 自动处理的,我怀疑手动创建不是正确的选择(大量代码重复,而且 HttpClient 类应该由 Angular 处理)。
这个问题的解决方案是什么?使用 Spring 框架也为单元测试项目处理依赖注入,我认为(并希望)在 Angular\Jasmine 中是相同的,但我到底该怎么做呢?
解决方案
Angular 会自动为您生成规范文件。如果不存在也没问题。让我们看看它会是什么样子:
import { PeopleListComponent } from "./people-list.component"
import { EventService } from '../event.service';
describe('people-list', () => {
let eventServiceSpy : jasmine.SpyObj<EventService>;
let component: PeopleListComponent;
let fixture: ComponentFixture<PeopleListComponent>;
beforeEach(async(() => {
const eventServiceSpyObj = jasmine.createSpyObj('EventService',['getPeople'])
TestBed.configureTestingModule({
declarations: [ PeopleListComponent ],
providers : [{ provide : EventService, useValue : eventServiceSpyObj }]
})
.compileComponents();
fixture = TestBed.createComponent(PeopleListComponent);
component = fixture.componentInstance;
eventServiceSpy = TestBed.inject(EventService);
}));
it('createEventObject() return 1', () => {
eventServiceSpy.getPeople.and.returnValue(of(1));
component.ngOnInit();
console.log(component.people); // this value should be one as return in mock service.
})
})
导入和所有可能存在错误。但这将是该方法的一般结构 创建组件时 beforeEach 函数中可能会出错。请让我知道错误。