为什么这个Jasmine单元测试总是失败(测试一个Angular组件),如果我的方法返回的输出是正确的?

问题描述 投票:0回答: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() {
    console.log("createEventObject() START");
    return 1;
  }

}

正如你所看到的,它包含了这个简单的方法,目前,它只是简单地返回值1:

createEventObject() { console.log("createEventObject() START"); return 1; }。

我想创建一个非常简单的Jasmine单元测试,断言这个方法的返回值是1,所以我实现了这样的功能。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);
        eventServiceSpy = <jasmine.SpyObj<EventService>><any>TestBed.inject(EventService);
        component = fixture.componentInstance;
        fixture.detectChanges();
    }));

    it('createEventObject()  return 1', () => {
        console.log("TEST 1 START");
        var methodOutput = component.createEventObject();
        console.log("METHOD OUTPUT: " + methodOutput);
        expect(methodOutput).toBe(1);
        //expect(1).toBe(1);
    })
})

正如你所看到的,我还插入了一些。控制台.log() 语句到测试箭头函数中,以检查被调用的输出。component.createEventObject() 而且它正确地返回1。

问题是测试失败,我不明白为什么。

在控制台中,我获得了这个错误信息。

developer@developer-virtual-machine:~/Documents/Angular-WS/SOC-Calendar$ ng test
10% building 2/2 modules 0 active23 05 2020 09:27:06.907:WARN [karma]: No captured browser, open http://localhost:9876/
23 05 2020 09:27:06.916:INFO [karma-server]: Karma v5.0.5 server started at http://0.0.0.0:9876/
23 05 2020 09:27:06.920:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
23 05 2020 09:27:06.927:INFO [launcher]: Starting browser Chrome
23 05 2020 09:27:12.013:WARN [karma]: No captured browser, open http://localhost:9876/
23 05 2020 09:27:12.211:INFO [Chrome 81.0.4044.129 (Linux x86_64)]: Connected on socket 0_E-_vH-y-N_pe-NAAAA with id 36927658
WARN: ''p-selectButton' is not a known element:
1. If 'p-selectButton' is an Angular component, then verify that it is part of this module.
2. If 'p-selectButton' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.'
Chrome 81.0.4044.129 (Linux x86_64): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
WARN: ''p-selectButton' is not a known element:
1. If 'p-selectButton' is an Angular component, then verify that it is part of this module.
2. If 'p-selectButton' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to supWARN: ''p-orderList' is not a known element:
1. If 'p-orderList' is an Angular component, then verify that it is part of this module.
2. If 'p-orderList' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.'
Chrome 81.0.4044.129 (Linux x86_64): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
WARN: ''p-orderList' is not a known element:
1. If 'p-orderList' is an Angular component, then verify that it is part of this module.
2. If 'p-orderList' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppreLOG: 'TEST 1 START'
Chrome 81.0.4044.129 (Linux x86_64): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
LOG: 'createEventObject() START'
Chrome 81.0.4044.129 (Linux x86_64): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
LOG: 'METHOD OUTPUT: 1'
Chrome 81.0.4044.129 (Linux x86_64): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
Chrome 81.0.4044.129 (Linux x86_64) people-list createEventObject()  return 1 FAILED
    Failed: Cannot read property 'then' of undefined
        at <Jasmine>
        at PeopleListComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/people-list/people-list.component.ts:29:34)
        at callHook (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4770:1)
        at callHooks (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4734:1)
        at executeInitAndCheckHooks (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4674:1)
        at refreshView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11998:1)
        at renderComponentOrTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12114:1)
        at tickRootContext (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13668:1)
        at detectChangesInRootView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13702:1)
        at RootViewRef.detectChanges (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:15420:1)
        at ComponentFixture._tick (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:331:1)
Chrome 81.0.4044.129 (Linux x86_64): Executed 1 of 1 (1 FAILED) (0 secs / 0.055 secs)
Chrome 81.0.4044.129 (Linux x86_64) people-list createEventObject()  return 1 FAILED
    Failed: Cannot read property 'then' of undefined
        at <Jasmine>
        at PeopleListComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/people-list/people-list.component.ts:29:34)
        at callHook (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4770:1)
        at callHooks (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4734:1)
        at executeInitAndCheckHooks (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:4674:1)
        at refreshView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:11998:1)
        at renderComponentOrTemplate (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:12114:1)
        at tickRootContext (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13668:1)
        at detectChangesInRootView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:13702:1)
        at RootViewRef.detectChanges (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:15420:1)
        at ComponentFixture._tick (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/__ivy_ngcc__/fesm2015/tChrome 81.0.4044.129 (Linux x86_64): Executed 1 of 1 (1 FAILED) (0.105 secs / 0.055 secs)
TOTAL: 1 FAILED, 0 SUCCESS
TOTAL: 1 FAILED, 0 SUCCESS

我还尝试用:

expect(methodOutput).toBe(1);

用:

expect(1).toBe(1);

以确保测试成功,但我还是得到了同样的错误,所以我认为这个问题与这个 叹为观止 行,但在我的测试的一些配置中。

为什么我会得到这个奇怪的错误?它到底是什么意思?我的代码有什么问题?我怎么才能修复它?

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

我看到了几个问题,可以说是测试模块没有正确配置。

  • 该组件包含几个依赖关系。比如 p-selectButton, p-orderList,等等。Angular试图解析这些标签,但失败了。解决办法 - 告诉Angular避免解析这些标签。
TestBed.configureTestingModule({
  ...
  schemas:[NO_ERRORS_SCHEMA],
});
  • fixture.detectChanges() 触发组件生命周期事件。ngOnInit 其中。而错误就发生在那里。
    Failed: Cannot read property 'then' of undefined
        at <Jasmine>
        at PeopleListComponent.ngOnInit 

只有一个 then 里面 ngOnInit.

this.eventService.getPeople().then(people => {this.people = people;});

现在让我们看看提供的模拟。

const eventServiceSpyObj = jasmine.createSpyObj('EventService',['getPeople'])
{ provide : EventService, useValue : eventServiceSpyObj }

看起来像是创建的间谍 eventServiceSpyObj 有方法 getPeople(). 读取错误 Cannot read property 'then' of undefined 可见 getPeople() 返回 undefined 而不是 Promise。为了解决这个问题,你需要模拟一下 getPeople

const eventServiceSpyObj = jasmine.createSpyObj('EventService',['getPeople'])
eventServiceSpyObj.getPeople.and.returnValue(Promise.resolve());

或者不要调用该方法 fixture.detectChanges(). 本测试不需要。

© www.soinside.com 2019 - 2024. All rights reserved.