【问题标题】:Angular 2 mocking an async service that calls another serviceAngular 2 模拟调用另一个服务的异步服务
【发布时间】:2017-06-17 16:39:13
【问题描述】:

我正在学习 Angular 2 测试(Karma、Jasmine)。我已经对 HTTP 服务进行了工作测试,主要来自 this Semaphore tutorial on services and testing。我通过通常的 async(inject([MyService], ...

我的实际程序有一个服务包装在一个服务中,如下所示。

@Injectable()
export class GlobalsService {
  private options: Option[] = [];
  error: any;

  constructor(private optionService: OptionService) { }

  public getGlobals(): void {
    let that = this;
    this.optionService
      .getOptions()
      .then(options => that.fillOptions(options))
      .catch(error => that.error = error);
  }
  [SNIP]

optionService.getOptions() 返回一个等待的 Promise,然后填充 globalService.options 列表。 globalsService.getGlobals() 要么同步调用,要么在隐藏其内容的异步(延迟)填充的地方调用。

export class AppComponent implements OnInit {
  constructor(private globalsService: GlobalsService) { }

  ngOnInit() {
    this.globalsService.getGlobals();
  }
  [SNIP]

我坚持的是如何在测试环境中调用 globalsService.getGlobals()。我想我应该通过 async() 调用它。

到目前为止,我的模拟 OptionService 是:

@Injectable()
export class MockOptionService {
  constructor() { }

  getOptions(): Promise<Option[]> {
    let options: Option[] = [
      { id: 'NY' } // truncated property list
    ];
    return Promise.resolve(options);
  }

}

然后我打算打电话给它:

  it('should get Option objects async',
    async(inject([GlobalsService, MockOptionService], (globalsService: GlobalsService, optionService: OptionService) => {

      globalsService.getGlobals()
        .then(() => {
          expect(globalsService.getOptions().length).toBe(1);
        });      

但是,我的“智能”程序员编辑器 (SublimeText) 说“属性 'then' 不存在于类型 'void'。”,让我不确定我是否应该使用 async(inject 或只使用 tick()。

评论,有人吗?

谢谢, 杰罗姆。

【问题讨论】:

    标签: angular testing mocking karma-jasmine angular-promise


    【解决方案1】:

    试试这个!

    it('should get Option objects async',
    async(inject([GlobalsService, MockOptionService], (globalsService: GlobalsService, optionService: OptionService) => {
    
      globalsService.getGlobals()
        .do(value => {
          expect(value.length).toBe(1);
        }).toPromise(); 
    })));
    

    【讨论】:

    • 不会改变任何事情。请参阅下面的答案。
    【解决方案2】:

    在摆弄和更多研究之后,我发现了两件事: * 我的测试是错误的。 globalsService.getGlobals() 返回 void。 .then 或 .do 说“属性不存在”是正确的。

    为了使测试正常工作,我所做的更改是添加一个设置子句,将 async(inject( 更改为 fakeAsync(inject( 并修复注入和声明。以下是有效的方法:

    describe('Globals Service', () => {
    
      beforeEach(() => {
    
        TestBed.configureTestingModule({
          providers: [
            { provide: OptionService, useClass: MockOptionService },
            { provide: GlobalsService, useClass: GlobalsService }
          ]
        });
      });
    
      fakeAsync(inject([GlobalsService, OptionService], (globalsService: GlobalsService,  optionService: OptionService) => {
          globalsService.getGlobals();
          tick();
          expect(globalsService.getOptions().length).toBe(1);
        })));
    
    });
    

    感谢大家的关注,感谢 Nidhin 的回复。现在我处理我的error() 处理——在handleError() 中报告一个空错误变量。但这是针对不同的支持电话。

    杰罗姆。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      • 2014-03-04
      • 2014-10-28
      • 2016-07-23
      相关资源
      最近更新 更多