角度单元测试-模拟REST服务调用

时间:2019-11-21 22:43:08

标签: angular unit-testing karma-jasmine

我正在为Angular应用程序编写单元测试,以测试前端功能,并尝试生成一种方法来模拟针对以下情况的rest服务调用:

我有一个定义如下的类:

import { Component, OnInit } from '@angular/core';
import {RestService} from "../../../../../services/rest.service";
import {ActivatedRoute, Router} from "@angular/router";

@Component({
  selector: 'app-example-class’,
  templateUrl: ‘./example-class.component.html',
  styleUrls: [‘./example-class.component.scss']
})
export class ExampleClass implements OnInit {

  myData: any = [];
  reloadInterval: any;
  constructor(private rest: RestService) {
    this.reloadInterval = setInterval(() => {
      this.getData();
    }, 10000);
  }

  ngOnInit() {
    this.getData();
  }

  ngOnDestroy(){
    clearInterval(this.reloadInterval);
  }

  getData() {
    this.rest.call(‘exampleClass’, this.rest.id).subscribe((data: {}) => {
      if (data['rows']) {
        this.myData = data['rows'].reduce((accumulator, currRow)=> accumulator + currRow.value, 0);
      }
    });
  }
}

我想使用Karma / Jasmine单元测试框架来专门测试我的“ getData()”方法。这是我创建的:

describe(‘ExampleClassComponent', () => {
  let component: ExampleClass;
  let fixture: ComponentFixture<ExampleClass>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
      ],
      declarations: [ ExampleClass ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ExampleClass);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create',
    inject(
      [HttpTestingController],
      (httpMock: HttpTestingController) => {
    expect(component).toBeTruthy();
  }));
});

这有效。组件被创建并且测试通过。但是,当我尝试执行以下操作时:

it('should test number of elements', ()=>{
    component.getData();
    expect(component.myData.length).toBe(1);
 });

这失败。它失败了,因为它试图通过对未运行的服务的剩余调用来调用getData()方法。我想以某种方式模拟该函数中进行的其余调用。我尝试像这样在测试类中创建MockRestService类:

class MockRestService extends RestService {
  myData = [
    {myData: 1}
  ];

  call(endpoint: string, params?: Object, data?: any, queryString?: string, isCustomUri?: boolean): Observable<any> {
    return of(this.myData);
  }
}

然后修改我的测试:

  it('should test number of elements', ()=>{
    let mockRestService = new MockRestService(null);
    component = new ExampleClass(mockRestService);
    component.getData();
    expect(component.myData.length).toBe(1);
  });

但这不起作用。是否可以模拟在getData中进行的其余调用以进行测试,如果可以,该如何进行?我非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您不需要单独的MockRestService类,但可以使用Jasmine的spyOn模拟RestService.call方法。可能如下所示。

it('should test number of elements', ()=> {

    // given
    const restService = TestBed.get(RestService);
    const data = {} // define your rest call data
    spyOn(restService, 'call').and.returnValue(of(restData));

    // when
    component.getData();

    // then
    expect(component.myData.length).toBe(1);
});