Angular2测试服务模拟

时间:2016-10-31 20:57:39

标签: unit-testing angular jasmine

我有一个简单的Angular2组件,它由以下

组成
import { Component, OnInit, Input } from '@angular/core';
import {FooterLinksService} from './footer-links.service';
import { environment } from '../../environments/environment';

    @Component({
        selector: 'app-footer-links',
        templateUrl: './footer-links.component.html',
        styleUrls: ['./footer-links.component.css'],
        providers: [FooterLinksService]
    })
    export class FooterLinksComponent implements OnInit {        

        constructor(private footerLinksService: FooterLinksService) {
            let footerLinks = this.footerLinksService.LoadFooterLinks();
        }    

    }

我正在尝试用Jasmine编写单元测试。现在我想模拟FooterLinksService,但我见过的大多数例子都涉及手动编写FooterLinksServiceMock。有没有其他方法可以使用自动生成模拟服务,如NSubStitute,我提供footerLinksService.LoadFooterLinks的预期返回值

1 个答案:

答案 0 :(得分:0)

如@JBNizet所述,你可以使用间谍。你要做的是获得测试中的实际服务,然后你可以监视一个方法,当调用该方法时,返回任意值。它可能看起来像

describe('component: FooterLinksComponent', () => {
  let fixture;
  let service;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        FooterLinksComponent
      ],
    });

    fixture = TestBed.createComponent(FooterLinksComponent);
    service = fixture.debugElement.injector.get(FooterLinksService);
  });

  it('should change message returned', () => {
    spyOn(service, 'LoadFooterLinks').and.returnValue('Hello new message');
    fixture.detectChanges();
    expect(fixture.componentInstance.message).toBe('Hello new message');
  });
});

您需要将构造函数内部访问服务的代码移动到ngOnInit。原因是因为

  1. 您正在使用@Component.providers,因此在创建组件之前不会创建该服务。
  2. 创建组件时,已调用构造函数。所以这并没有给你时间来设置间谍。当您使用ngOnInit时,在致电ngOnInit
  3. 之前,系统不会调用fixture.detectChanges()