首页 > 解决方案 > 如何使用 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 中是相同的,但我到底该怎么做呢?

标签: angulartypescriptunit-testingjasmineangular-unit-test

解决方案


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 函数中可能会出错。请让我知道错误。


推荐阅读