【问题标题】:Angular2 testing service mocksAngular2 测试服务模拟
【发布时间】:2017-03-14 00:36:09
【问题描述】:

我有一个简单的 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 的预期返回值

【问题讨论】:

  • 阅读 jasmine 文档。涵盖了模拟和间谍。
  • 我实际上看到了这一点,但问题是我遇到的所有示例,即使在 Angular 站点angular.io/docs/ts/latest/guide/testing.html 上似乎都指向实际创建一个 mockedService (FooterLinksService) 而不是使用 speis?这是标准方法吗?如果是,为什么不通过间谍?
  • 可能是因为文档尽量不同时引入太多的概念,同时也展示了不特定于 jasmine 的代码。如果您了解什么是 mock 和 spy,您当然可以使用 jasmine 来创建它们,而不是手动创建它们。为什么你不能?是什么阻止你尝试呢?
  • 另请注意,用于测试的官方 Angular 文档确实使用了 jasmine 间谍。只需在angular.io/docs/ts/latest/guide/testing.html中搜索间谍

标签: unit-testing angular jasmine


【解决方案1】:

正如@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 时,在您调用fixture.detectChanges() 之前不会调用ngOnInit

【讨论】:

  • 我遇到了类似的问题。您的FooterLinkService 是否在其构造函数中注入Http(来自@angular/http)?如果是这样,您的项目是否有可能是公共项目(因此我可以查看您的代码以帮助我解决问题)?谢谢!
  • @DavidL 你还需要imports: [ HttpModule ]
猜你喜欢
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
相关资源
最近更新 更多