【问题标题】:Unable to cover a service in constructor angular unit test无法在构造函数角度单元测试中覆盖服务
【发布时间】:2019-11-01 04:12:35
【问题描述】:

我该如何解决这个问题?

大家好,我对使用 karma 和 jasmine 对 angular 6 进行单元测试非常陌生

我正在尝试覆盖我的组件构造函数内部但无法执行的服务。 'it' 块 'should create component' 覆盖了构造函数中的行,但服务返回的数据除外。

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();
    });
    });

【问题讨论】:

    标签: angular jasmine angular-unit-test


    【解决方案1】:

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

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

    所以你有可能:

    首先你可以创建一个存根服务,它已经返回了一个特定的可观察对象,它发出一个值 X。然后你可以在你的 TestBed 中提供这个存根,并带有{provide: YourService, useValue: serviceStub},其中 serviceStub 看起来像这样:const serviceStub = {yourMethod: ()=&gt; of(YOUR_TEST_VALUE}

    问题是,在您的测试用例中,您无法期望调用服务方法,但您可以测试,从您的 observable 发出的值设置在您的组件中。此外,如果您想为不同的用例更改值 X,则需要创建多个描述,每个描述提供不同版本的服务模拟。

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

    对于您的应用来说,它不会产生影响,并且会更容易测试。

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

    话虽如此,如果您要将订阅移动到 ngOnInit 方法中,您只需从 beforeEach 函数中删除 fixture.detectChanged 并将其移动到您的测试用例 after 您的 spyOn 中。

    【讨论】:

      猜你喜欢
      • 2021-05-21
      • 2021-03-29
      • 2017-11-19
      • 1970-01-01
      • 2020-06-05
      • 2015-11-30
      • 1970-01-01
      • 2015-06-18
      • 2020-12-04
      相关资源
      最近更新 更多