【问题标题】:How to inject ts-mockito into Angular 4 component test如何将 ts-mockito 注入 Angular 4 组件测试
【发布时间】:2018-04-08 03:57:57
【问题描述】:

类似于this question 上的typemoq 注入,如何将ts-mockito 对象注入到angular 的TestBed.configureTestingModule() 中?我能找到的任何example ts-mockito 测试都与角度无关。

考虑以下要测试的最小工作示例——它包含一个ProgressComponent,在我们正在模拟的后端有一个ProgressService。服务很简单:

import { Injectable } from '@angular/core';

@Injectable()
export class ProgressService {
    private currentState: string = '1';

    constructor() {
    }

    setCurrentState(state: string) {
        this.currentState = state;
    }

    getCurrentState(){
        return this.currentState
    }

}

要在没有ts-mockito 的情况下模拟它,我们只需扩展类。

import {ProgressService} from "../../../progress.service";

export class MockProgressService extends ProgressService{}

然后在测试ProgressComponent 时,MockProgressService 被传递给 TestBed。

import {async, ComponentFixture, getTestBed, TestBed} from '@angular/core/testing'

import { ProgressComponent } from './progress.component'
import {ProgressService} from "../progress.service"
import {MockProgressService} from "../shared/services/progress/progress.mock";

describe('ProgressComponent', () => {
  let injector: TestBed
  let mockService: ProgressService
  let fixture: ComponentFixture<ProgressComponent>
  let component: ProgressComponent

  beforeEach(async() => {
    TestBed.configureTestingModule({
      declarations: [ ProgressComponent ],
      providers: [{provide: ProgressService, useClass: MockProgressService}]
    }).compileComponents()

    injector = getTestBed()
    fixture = TestBed.createComponent(ProgressComponent)
    component = fixture.componentInstance
    mockService = injector.get(ProgressService)

    fixture.detectChanges();
  });
});

Angular 测试框架通过TestBed 引入依赖注入。 我们如何在 Angular 的测试设置中使用 mockito? 例如,如何使 sn-p injector.get(ProgressService) 与 ts-mockito 模拟兼容?

【问题讨论】:

  • class MockProgressService extends ProgressService 没有多大意义,所以不清楚 ts-mockito 对象有什么问题。您可以使用 useValue: ...useFactory: () =&gt; ... 使用您想要的任何对象模拟服务
  • 角度教程通过扩展实际模拟的类来创建模拟对象。所以 MockProgressService 只是扩展 ProgressService (在这种情况下并没有覆盖方法)。所以不是 useClass,我应该 useValue 引用我手动实例化的 mockito 对象?
  • 是的,就是这样。我不确定该教程的意义何在,但出于实际原因,通常在模拟的课程中扩展真实课程是不可以的。

标签: angular unit-testing typescript


【解决方案1】:

如果一个提供者应该用另一个对象而不是类来模拟,它应该使用useValueuseFactory

茉莉花是:

providers: [{
  provide: ProgressService,
  useValue: jasmine.createSpyObj('ProgressService', [...])
}]

对于 ts-mockito,它可以是:

progressServiceMock = mock(ProgressService);
...
providers: [{provide: ProgressService, useValue: instance(progressServiceMock)}]

虽然继承像class MockProgressService extends ProgressService 这样的模拟类frim 原始类通常没有好处。如果打算模拟某些方法,可以在真实的类实例或类原型上用jasmine.spy(或当前测试框架具有的对应物)模拟它们。当一个类不是在当前单元测试中测试的类时,模拟/存根所有方法而不是多个方法有利于测试隔离。

【讨论】:

  • 这篇关于模拟与间谍的帖子帮助我理解了您列出的两种情况的区别 (stackoverflow.com/questions/12827580/…) 感谢您的精彩回答
  • 不客气。从来没有在实际工作中使用过后者。 Jasmine 间谍非常多才多艺,对于更复杂的东西,Mocha 存根很好。我对 mockito 和 typemoq 提供的默认行为不满意。它们主要用于自动存根所有类方法,同时通过一些手动控制贪婪地模拟它们可以更容易地发现测试代码中的错误。 Typemoq 有“严格”模式来解决这个问题,但看起来 mockito 没有这样的东西。
猜你喜欢
  • 1970-01-01
  • 2021-07-23
  • 2017-06-18
  • 2020-12-21
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
相关资源
最近更新 更多