在单元测试中从未调用订阅内的角度函数 [英] Angular - Function inside subscribe never called in unit test

查看:0
本文介绍了在单元测试中从未调用订阅内的角度函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试我的导航功能是否被称为删除车辆。但它似乎从来没有打过电话。我认为这可能与以下事实有关:它是一个异步功能,但即使当我等待完全订阅完成时,它也不起作用。

.ts:

deleteVehicle(): void {
    if (confirm('Bent u zeker dat u deze wagen wilt verwijderen?')) {
      this.apiService.deleteVehicle(this.selectedVehicle.id).subscribe(() => this.navigateToListVehicleComponent());
    }
  }

规格:

beforeEach(() => {
    fixture = TestBed.createComponent(VehicleDetailsComponent);
    component = fixture.componentInstance;

    apiService = TestBed.get(ApiService);
    fixture.detectChanges();
});
describe('#deleteVehicle', () => {
    it('should navigate to list vehicle component', fakeAsync(() => {
      spyOn(window, 'confirm').and.returnValue(true);
      spy = spyOn(apiService, 'deleteVehicle').withArgs(component.selectedVehicle.id).and.callThrough();
      let navigateSpy = spyOn(component,'navigateToListVehicleComponent').and.callThrough();

      component.deleteVehicle();
      tick();
      expect(spy).toHaveBeenCalled();
      expect(navigateSpy).toHaveBeenCalled();
    }));
  });

service.ts:

private deleteFromAPI(url): any {
    return this.http
    .delete(this.BASE_API_URL + url)
    .pipe(catchError(this.handleError));
}
deleteVehicle(id: number): any {
    return this.deleteFromAPI('vehicle/' + id);
}

在我的测试床中,我导入了HttpClientTestingModule。

错误: 预期已调用间谍NavigateToListVehicleComponent。

有人知道我做错了什么吗?

推荐答案

我的测试策略是将apiService.deleteVehicle方法存根,这样它就不会有副作用(通过网络发送真正的Http请求)。

使用angularv11+:

的单元测试解决方案

example.component.ts

import { Component } from '@angular/core';
import { ApiService } from './api.service';

@Component({})
export class ExampleComponent {
  selectedVehicle = {
    id: 1,
  };
  constructor(private apiService: ApiService) {}
  navigateToListVehicleComponent() {
    console.log('navigateToListVehicleComponent real implementation');
  }

  deleteVehicle(): void {
    if (confirm('Bent u zeker dat u deze wagen wilt verwijderen?')) {
      this.apiService
        .deleteVehicle(this.selectedVehicle.id)
        .subscribe(() => this.navigateToListVehicleComponent());
    }
  }
}

api.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ApiService {
  BASE_API_URL = 'http://localhost';
  constructor(private http: HttpClient) {}

  private deleteFromAPI(url): any {
    return this.http
      .delete(this.BASE_API_URL + url)
      .pipe(catchError(this.handleError));
  }
  private handleError(err) {
    return of(err);
  }
  deleteVehicle(id: number): any {
    return this.deleteFromAPI('vehicle/' + id);
  }
}

example.component.spec.ts

import { HttpClient, HttpClientModule } from '@angular/common/http';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { of } from 'rxjs';
import { ApiService } from './api.service';
import { ExampleComponent } from './example.component';

fdescribe('#deleteVehicle', () => {
  let apiService: ApiService;
  let fixture: ComponentFixture<ExampleComponent>;
  let component: ExampleComponent;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [ExampleComponent],
        imports: [HttpClientModule],
        providers: [ApiService, HttpClient],
      })
        .compileComponents()
        .then(() => {
          fixture = TestBed.createComponent(ExampleComponent);
          apiService = TestBed.get(ApiService);
          component = fixture.componentInstance;
          fixture.detectChanges();
        });
    })
  );
  it('should navigate to list vehicle component', () => {
    const confirmSpy = spyOn(window, 'confirm').and.returnValue(true);
    const deleteVehicleSpy = spyOn(apiService, 'deleteVehicle')
      .withArgs(component.selectedVehicle.id)
      .and.returnValue(of('deleteVehicle fake implementation'));

    let navigateSpy = spyOn(
      component,
      'navigateToListVehicleComponent'
    ).and.stub();

    component.deleteVehicle();

    expect(confirmSpy).toHaveBeenCalledOnceWith(
      'Bent u zeker dat u deze wagen wilt verwijderen?'
    );
    expect(deleteVehicleSpy).toHaveBeenCalledOnceWith(1);
    expect(navigateSpy).toHaveBeenCalled();
  });
});

单元测试结果:

这篇关于在单元测试中从未调用订阅内的角度函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆