【问题标题】:Angular Jasmine testing having a service stub for a private service, then checking if a function to the private service is called?Angular Jasmine 测试有一个私有服务的服务存根,然后检查是否调用了私有服务的函数?
【发布时间】:2018-11-19 00:08:33
【问题描述】:

我正在测试一个角度组件,其中一个功能是调用私有的“通知服务”。无论如何,我在测试期间出于各种原因为此服务提供了一个存根。

现在我遇到的问题是,在尝试对其进行简单检查时,我仍然收到错误 'notification is a private service'

expect(component.notification.done()).toHaveBeenCalled();

在我的测试平台上,我有:

  { provide: NotificationService, useClass: NotificationStub }

在我的 NotificationStub 类中,我只是在里面有一个返回的函数;

如果该服务是私有的,我如何检查是否正在调用该函数?出于各种可维护性的原因,我不想将其公开。

【问题讨论】:

  • 你不能在存根中公开等效函数,监视它并测试它是否被调用?
  • 但它是在构造函数中注入的服务。我该如何修改?
  • 这里发生的事情肯定比你到目前为止所详述的要多。这是一个stackblitz,我在其中注入了一个间谍对象来代替私有服务,它工作正常。随意 fork 那个 stackblitz,用你自己的数据替换并显示你遇到的错误。

标签: angular typescript jasmine stub angular-test


【解决方案1】:

您可以使用const doneSpy = spyOn(NotificationStub.prototype, 'done') 将间谍安装到done 方法上。然后,您可以为doneSpy 进行断言,而不是尝试获取私有服务。

这是一个使用angular v11+ 的示例:

example.component.ts:

import { Component, OnInit } from '@angular/core';
import { NotificationService } from './notification.service';

@Component({})
export class ExampleComponent implements OnInit {
  constructor(private notification: NotificationService) {}

  ngOnInit() {
    this.notification.done();
  }
}

notification.service.ts:

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

@Injectable()
export class NotificationService {
  done() {
    console.log('Your real implementation');
  }
}

example.component.spec.ts:

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ExampleComponent } from './example.component';
import { NotificationService } from './notification.service';

class NotificationStub {
  done() {
    console.log('fake implementation');
  }
}

fdescribe('53366751', () => {
  let fixture: ComponentFixture<ExampleComponent>;
  let component: ExampleComponent;
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [ExampleComponent],
        providers: [
          { provide: NotificationService, useClass: NotificationStub },
        ],
      })
        .compileComponents()
        .then(() => {
          fixture = TestBed.createComponent(ExampleComponent);
          component = fixture.componentInstance;
        });
    })
  );

  it('should pass', () => {
    const doneSpy = spyOn(NotificationStub.prototype, 'done').and.callThrough();
    fixture.detectChanges();
    expect(doneSpy).toHaveBeenCalled();
  });
});

单元测试结果:

LOG: 'fake implementation'
Chrome Headless 80.0.3987.87 (Mac OS 10.13.6): Executed 0 of 36 SUCCESS (0 secs / 0 secs)
Chrome Headless 80.0.3987.87 (Mac OS 10.13.6): Executed 2 of 36 (skipped 34) SUCCESS (0.105 secs / 0.024 secs)
TOTAL: 2 SUCCESS

测试覆盖率:

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多