将作为参数传递的回调模拟到对象中

时间:2017-08-03 20:48:24

标签: javascript angular unit-testing typescript karma-jasmine

我有一个我尝试测试的模态服务,但不幸的是我不知道我应该如何模拟回调«ok»和«cancel»作为参数传递给服务。我的单元测试通过,但覆盖需要一些爱:

我的组件类:

export class TestComponent {

    constructor(private _modalService : ModalService) {}

    public show() : void {
        this._modalService.showModal(DefaultModalComponent, {
            ok: () => {
                alert("Ok have been clicked.");
                this._modalService.hide();
            },
            cancel: () => {
                alert("Cancel have been clicked.");
                this._modalService.hide();
            }
        });
    }
}

我的单元测试类看起来像这样:

describe("TestComponent", () => {

    let _modalService = jasmine.createSpyObj("ModalService", ["show"]);

    beforeEach(() => {
        TestBed.resetTestEnvironment();
        TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
        TestBed.configureTestingModule({
            imports: [BrowserAnimationsModule],
            schemas: [NO_ERRORS_SCHEMA],
            declarations: [TestComponent],
            providers: [{ provide: ModalService, useValue: _modalService }]
        });
     });

     let _component: any;
     let _element: any;

     beforeEach(done => {
         TestBed.compileComponents().then(() => {
             let fixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
             fixture.detectChanges();
             _component = fixture.componentInstance;
             _element = fixture.nativeElement;

             done();
         });
     });

    describe("show()", () => {
        it("should have called show method from service with parameters provided", done => {
            _component.show();

            expect(_modalService.show).toHaveBeenCalled();

            done();
        });
    });
});

1 个答案:

答案 0 :(得分:1)

该服务可以以对测试友好的方式进行重构:

modalOkHandler = () => { ... }

modalCancelHandler = () => { ... }

public show() : void {
    this._modalService.showModal(DefaultModalComponent, {
        ok: this.modalOkHandler,
        cancel: this.modalCancelHandler
    });
}

这样可以在被调用的方法上声明回调:

_component.show();
expect(_modalService.show).toHaveBeenCalledWith(DefaultModalComponent, {
  ok: modalService.modalOkHandler,
  cancel: modalService.modalCancelHandler
});

替代方案不太方便。对于匿名函数,应该测试方法参数:

_component.show();
expect(_modalService.show).toHaveBeenCalledWith(DefaultModalComponent, {
  ok: jasmine.any(Function),
  cancel: jasmine.any(Function)
});

const [, { ok, cancel }] = _component.show.calls.first().args;
spyOn(window, 'alert');
expect(_modalService.hide).toHaveBeenCalledTimes(0);
ok();
expect(alert).toHaveBeenCalledWith(...);
expect(_modalService.hide).toHaveBeenCalledTimes(1);
...