为什么我在Jasmine单元测试中获得这个错误?

问题描述 投票:0回答:1

我正试图使用 茉莉花 第一次按照一些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)

什么是错的?我如何才能正确测试我的组件方法?

angular unit-testing jasmine angular-unit-test
1个回答
1
投票

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);
© www.soinside.com 2019 - 2024. All rights reserved.