Angular-模拟订阅组件的方法

时间:2019-01-10 08:25:35

标签: angular unit-testing jasmine observable karma-runner

我在组件中有一个方法,可以像这样调用服务方法:

method() {
    // Code before ...

    this.productService.getProducts().subscribe((data: any[]) => {
        const products = [];

        // Many calculations on data ...

        this.products = products;
    }); 
}

对于单元测试,我需要在调用productService.getProducts()时模拟返回的数据。

我做了很多研究,但是没有找到任何解决方案。我该怎么办?

1 个答案:

答案 0 :(得分:0)

你应该看看Component with async service。我们可以让 spy 返回一个同步的 Observable 和 this.productService.getProducts() 方法的测试数据。

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

example.component.ts

import { Component } from '@angular/core';
import { ProductService } from './product.service';

@Component({})
export class ExampleComponent {
  products: any[];
  constructor(private productService: ProductService) {}
  method() {
    this.productService.getProducts().subscribe((data: any[]) => {
      this.products = data;
    });
  }
}

product.service.ts

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

@Injectable()
export class ProductService {
  getProducts() {
    return of(['Your real implementation']);
  }
}

example.component.spec.ts

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { of } from 'rxjs';
import { ExampleComponent } from './example.component';
import { ProductService } from './product.service';

fdescribe('54124518', () => {
  let productServiceStub: jasmine.SpyObj<ProductService>;
  let fixture: ComponentFixture<ExampleComponent>;
  let component: ExampleComponent;
  beforeEach(
    waitForAsync(() => {
      productServiceStub = jasmine.createSpyObj('ProductService', [
        'getProducts',
      ]);

      TestBed.configureTestingModule({
        declarations: [ExampleComponent],
        providers: [{ provide: ProductService, useValue: productServiceStub }],
      })
        .compileComponents()
        .then(() => {
          fixture = TestBed.createComponent(ExampleComponent);
          component = fixture.componentInstance;
        });
    })
  );

  it('should pass', () => {
    productServiceStub.getProducts.and.returnValue(of(['fake implementation']));
    component.method();
    expect(component.products).toEqual(['fake implementation']);
    expect(productServiceStub.getProducts).toHaveBeenCalled();
  });
});

单元测试结果:

enter image description here