我正试图使用 茉莉花 第一次按照一些examp,e和我发现一些问题。
所以我有这个 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() 方法,目前只能返回1(我想尽可能的简单)。我的第一个单元测试必须测试这个方法,简单地检查返回值是否为1。
正如你所看到的,前面的方法取了一个 事件服务 服务实例注入到构造函数中。
这就是 EventSerive 类的代码。
import { Injectable } from '@angular/core';
//import { Http } from '@angular/http';
import { HttpClientModule, HttpClient } from '@angular/common/http'
@Injectable()
export class EventService {
private events = [
{id: 1, title: 'All Day Event', start: '2017-02-01'},
{id: 2, title: 'Long Event', start: '2017-02-07', end: '2017-02-10'},
{id: 3, title: 'Repeating Event', start: '2017-02-09T16:00:00'},
];
private people = [
{id: 1, name: "PERSONA 1"},
{id: 2, name: "PERSONA 2"},
{id: 3, name: "PERSONA 3"},
{id: 4, name: "PERSONA 4"},
{id: 5, name: "PERSONA 5"},
]
constructor(private http: HttpClient) {}
/*
getEvents(): Promise<any[]> {
return this.http.get('assets/json_mock/calendarevents.json')
.toPromise()
.then(res => JSON.parse(JSON.stringify(res)).data)
.then(res => {
console.log(res);
// you returned no value here!
return res;
})
}
*/
getEvents(): Promise<any[]> {
return Promise.all(this.events)
.then(res => {
console.log(res);
// you returned no value here!
return res;
})
}
addEvent(event) {
//this.events.push(event);
//console.log("EVENT:")
//console.log(event.event.title);
console.log(event.event.start);
console.log(event);
const newEvent = {id: 5, title: event.event.title, start: event.event.start, end: event.event.end};
this.events.push(newEvent);
console.log(this.events);
}
getPeople(): Promise<any[]> {
return Promise.all(this.people)
.then(res => {
console.log(res);
return res;
})
}
}
正如你所看到的,这个方法本身采取了另一个注入到构造函数中的对象(the HttpClient 来执行HTTP请求)。)
好了,现在我想实现 createEventObject() 方法测试到我的单元测试中。所以我有这样的 people-list.component.spec.ts 文件,我完全不知道这在逻辑上是否正确..:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { PeopleListComponent } from "./people-list.component"
import { EventService } from '../event.service';
import {HttpClientTestingModule} from '@angular/common/http/testing';
describe('people-list', () => {
let component: PeopleListComponent;
let fixture: ComponentFixture<PeopleListComponent>;
let eventServiceSpy : jasmine.SpyObj<EventService>;
beforeEach(async(() => {
const eventServiceSpyObj = jasmine.createSpyObj('EventService',['getPeople'])
TestBed.configureTestingModule({
declarations: [PeopleListComponent],
imports: [HttpClientTestingModule],
providers : [{ provide : EventService, useValue : eventServiceSpyObj }]
});
// Create a testing version of my PeopleListComponent:
fixture = TestBed.createComponent(PeopleListComponent);
eventServiceSpy = TestBed.inject(EventService);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('createEventObject() return 1', () => {
expect(component.createEventObject()).toBe(1)
})
})
我完全不确定这在逻辑上是否正确... ...
问题是目前IDE在这一行给我一个错误。
eventServiceSpy = TestBed.inject(EventService);
错误是:
Type 'EventService' is not assignable to type 'SpyObj<EventService>'.
Type 'EventService' is not assignable to type '{ getEvents: (() => Promise<any[]>) & Spy<() => Promise<any[]>>; addEvent: ((event: any) => void) & Spy<(event: any) => void>; getPeople: (() => Promise<any[]>) & Spy<...>; }'.
Types of property 'getEvents' are incompatible.
Type '() => Promise<any[]>' is not assignable to type '(() => Promise<any[]>) & Spy<() => Promise<any[]>>'.
Type '() => Promise<any[]>' is missing the following properties from type 'Spy<() => Promise<any[]>>': and, calls, withArgsts(2322)
什么是错的?我如何才能正确测试我的组件方法?
TypeScript工具不是那么智能。
let eventServiceSpy : jasmine.SpyObj<EventService>;
eventServiceSpy = TestBed.inject(EventService);
eventServiceSpy
是类型 jasmine.SpyObj<EventService>;
. 根据打字的方法 TestBed.inject(EventService);
将返回类型为 EventService
而在Angular DI中,它可以为任何注入标记提供任何对象(在这种情况下,注入标记是类 EventService
). 上面你提供了类型为 jasmine.SpyObj<EventService>
:
providers : [{ provide : EventService, useValue : eventServiceSpyObj }
所以现在的方法是 TestBed.inject(EventService);
将提供类型为 jasmine.SpyObj<EventService>
. 但是开发工具到目前为止还没有那么智能,无法正确处理这里的输入。一个变通的办法就是铸造。
eventServiceSpy = <jasmine.SpyObj<EventService>><any>TestBed.inject(EventService);