无法在构造函数角单元测试中涵盖服务

时间:2019-06-18 13:33:27

标签: angular jasmine angular-unit-test

我该如何解决?

大家好,我对使用业力和茉莉的角度6单元测试很陌生

我试图介绍一种服务,该服务位于组件的构造函数内部,但无法执行。 “ it”块“应创建组件”涵盖了构造函数内部的行,但服务所返回的数据除外。

component.ts

  constructor(public firstService: FirstService, public secondService: SecondService) {

    let localData :any
    let id = this.secondService.getId()
    let initialId = this.secondService.getInitialId()

    this.firstService.getRevisions(id, initialId).subscribe((data) => {
      if (data && data.content) {
         localData = data.content || [];
      }
    });
    }

component.spec.ts

 describe('TestComponent', () => {
      let component: TestComponent;
      let fixture: ComponentFixture<TestComponent>;
      let firstService: FirstService;
      let secondService: SecondService;

     beforeEach(() => {
      TestBed.configureTestingModule({
      declarations: [TestComponent],
      providers: [FirstService, SecondService]
     })
      .compileComponents();
     });
     beforeEach(() => {
     firstService = TestBed.get(FirstService);
     fixture = TestBed.createComponent(TestComponent);
     component = fixture.componentInstance;
     secondService = TestBed.get(SecondService);
     fixture.detectChanges();
     });

    it('should create Component', () => {
    expect(component).toBeTruthy();
    const mockData = {
      "content": [
        {
          "name": "String",
        }
      ],
    }
    spyOn(firstService, "getRevisions").and.callFake(() => {
      return of({ mockData });
    });
    spyOn(secondService, 'getId');
    spyOn(secondService, 'getInitialId');

    fixture.whenStable().then(() => {
      expect(firstService.getRevisions).toHaveBeenCalled();
    });
    });

1 个答案:

答案 0 :(得分:0)

调用构造函数后,您正在监视服务。

在您的TestBed上调用方法compileComponents()时,将调用构造函数。

因此,您必须具备各种可能性:

首先,您可以创建一个存根服务,该存根服务已经返回一个特定的可观察对象,并发出一个值X。然后,您可以在TestBed中为该存根提供{provide: YourService, useValue: serviceStub},其中serviceStub如下所示:const serviceStub = {yourMethod: ()=> of(YOUR_TEST_VALUE}

问题是,尽管在测试用例中您无法期望调用了服务方法,但可以进行测试,但观察对象的发射值是在组件内部设置的。此外,如果要为不同的用例更改值X,则需要创建多个描述,每个描述提供不同版本的服务模拟。

恕我直言,更好的方法是将订阅移到onInit生命周期挂钩中。

对于您的应用,这没有什么不同,并且测试起来更容易。

第一次触发fixture.detectChanges时会调用测试中的onInit生命周期。

话虽如此,如果将预订移至ngOnInit方法中,则只需从beforeEach函数中删除fixture.detectChanged并将其移至测试用例中之后暗中监视。