【问题标题】:Angular 4 testing: fakeAsync with InjectAngular 4 测试:使用 Inject 的 fakeAsync
【发布时间】:2018-04-10 19:21:27
【问题描述】:

我正在尝试使用在构造函数中调用并包含 observable 的私有方法来测试服务:

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/interval';

@Injectable()
export class SomeService {

  private booleanValue: boolean = false;

  constructor() {
    this.obsMethod();
  }

  private obsMethod() {
    Observable.interval(5000).subscribe(() => {
      this.booleanValue = !this.booleanValue;
    });
  }

  public getBooleanValue() {
    return this.booleanValue;
  }
}

我准备了三个规格。首先使用new 运算符创建的简单服务实例。它有效。其次是TestBed.get() 注入。它也有效。

当我在 beforeEach 中使用 inject 时,规范不起作用。但为什么? fakeAsyncinject 同时使用有问题吗?如何同时使用它们?

我在 plunker 上创建了带有服务和三个规格的工作演示。

https://embed.plnkr.co/dw6tCGXH6LWlJuqNuQl8/

【问题讨论】:

    标签: angular testing jasmine inject


    【解决方案1】:

    第三个规范的问题在于,可观察的区间是在fakeAsync() 函数之外创建的,这意味着它使用真正的setInterval() 函数,因此测试函数中的所有断言都在 5 之前运行得很好秒,因此对更改值的最后一个断言测试失败。

    我让它工作的一种方法是将可观察对象的初始化分离到一个单独的 init() 方法中,然后可以从测试中的 fakeAsync() 函数内部调用该方法以允许 tick() 正常工作.

    updated Plunkr is here

    相关代码:

    服务:

    @Injectable()
    export class SomeService {
    
      private booleanValue: boolean = false;
    
      constructor() {
      }
    
      public init() {
        this.obsMethod();
      }
    
      private obsMethod() {
        Observable.interval(5000).subscribe(() => {
            this.booleanValue = !this.booleanValue;
        });
      }
    
      public getBooleanValue() {
        return this.booleanValue;
      }
    }
    

    最终测试:

    describe('Some service specs with beforeEach Inject', () => {
    
      let serv: SomeService;
    
      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [
            SomeService
          ]
        });
      });
    
      beforeEach(inject([SomeService], (ss) => {
        serv = ss;
      }));
    
      it('Third - not working spec', fakeAsync(() => {
        serv.init();
        expect(serv.getBooleanValue()).toBe(false);
        tick(5000 - 1);
        expect(serv.getBooleanValue()).toBe(false);
        tick(2);
        expect(serv.getBooleanValue()).toBe(true);
        discardPeriodicTasks();
      }));
    });
    

    【讨论】:

    • 感谢您的回答,但您已更改应用程序代码进行测试。我不想那样做。
    • @Coosec 当然,我明白了。那么,也许坚持使用TestBed.get() 选项。这样,您将在 fakeAsync() 调用中实例化服务,但不必担心它的依赖关系。
    猜你喜欢
    • 2019-02-18
    • 1970-01-01
    • 2017-08-15
    • 2018-05-13
    • 1970-01-01
    • 2017-11-27
    • 2020-08-27
    • 1970-01-01
    • 2019-07-03
    相关资源
    最近更新 更多