angular 带有 toHaveBeenCalled 的茉莉花测试

angular jasmine test with toHaveBeenCalled

我正在尝试为以下功能编写单元测试:

onNextClick() {
    this.toast.clear();

    let checkedSubservices = new Array<number>();
    for (let i = 0; i < this.subSevices.length; i++) {
        if (this.subSevices[i].checked) {
            checkedSubservices.push(this.subSevices[i].id);
        }
    }

    if (checkedSubservices.length > 0)
    {
        this.bookService.setSubserviceIds(checkedSubservices);
        this.stepService.getNextStepByController(StepControllerNames.AllocationStepController)
            .then((ret: StepControllerReturnInfo) => {
                this.goToControllerTarget(ret);
            }).catch((error) => {
                // Error
            });
    }
    else
    {
        let options = { positionClass: 'toast-top-center', preventDuplicates: true };
        this.toast.error("Error.", "", options);
    }
}

我想测试 goToControllerTarget 是否已被调用。所以我创建了以下测试:

it('onNextClick a service is checked', fakeAsync(() => {
    let ret = new ReturnInfo();

    let services = new Array<any>();
    services.push({id: 1, title: "Tite 1"});
    services.push({id: 2, title: "Tite 2"});
    services.push({id: 3, title: "Tite 3"});

    component.subSevices = services;
    const spy = spyOn(stepService, "getNextStepByController").and.returnValue(Promise.resolve(ret));
    const spy2 = spyOn(component, "goToControllerTarget");

    // Test Function
    component.onNextClick();
    tick(0);

    expect(spy2).toHaveBeenCalled();
}));

测试失败,因为 goToControllerTarget 函数没有被调用。我已经调试并且调用了 catch 代码路径而不是 then。

有时Angular测试无法调用某个服务功能,因为组件定义不正确。如果该服务在 Angular 组件中被列为提供者并且未在 app.module.ts 中定义,则测试可能会失败:

@Component({
  selector: 'my-component',
  templateUrl: 'my-component.html',
  providers: [
    MyService,
 ]
})

在这种情况下,在测试中模拟服务不起作用..

it('should not work', async(inject([MyService], (myService) => {
  ..
  spyOn(myService, 'save').and.returnValue(Observable.of(someCalculation));

..我们必须将服务添加到 app.module.ts 并将其从提供商列表中删除以使其正常工作。

美好的一天!我想它应该可以工作:

expect(spy2.calls.any()).toBeTruthy();