How do you unit test that methods such as ok() were called in aurelia-dialog using jasmine?

377 Views Asked by At

How do I go about unit testing a method that calls the DialogController? I want to test that this.controller.ok() was called.

ReprocessLotDialog.js

@inject(DialogController)
export class ReprocessLotDialog {
    constructor(dialogController) {
        this.controller = dialogController;
    }


    commitReprocessingLot() {    
        this.controller.ok({
            reprocessLot: this.model
        });
    }    

    commitIncompleteBags(){
       ... do stuff ....
       this.commitReprocessingLot();
    }
}

myDialog.spec.js I've tried this but can't get it to work

describe("The ReprocessLotDialog module", ()=> {
    let sut;

    beforeEach(()=> {
        var container = new Container().makeGlobal();
        container.registerInstance(DialogController,controller => new DialogController());
        sut = container.get(ReprocessLotDialog);
    });


     it("commitReprocessingLot() should call controller.ok", (done)=> {    
        spyOn(sut, "controller.ok");

        sut.commitIncompleteBags();
        expect(sut.controller.ok).toHaveBeenCalled();
        done();
    });
});

The test fails with TypeError: 'undefined' is not a function (evaluating 'this.controller.ok({ reprocessLot: this.model })')

As far as I understand it I'm passing the DialogController through DI into the container and container.get(ReprocessLotDialog) injects the DialogController into the ctor.

I've also tried container.registerInstance(DialogController,{"dialogController":DialogController}); but that doesn't work either.

Many thanks

2

There are 2 best solutions below

1
Ashley Grant On BEST ANSWER

Your unit tests shouldn't be utilizing the DI container. You simply new up an instance of ReprocessLotDialog and pass in a mock of DialogController that you created. If you're using Jasmine, it would look something like this:

describe("The ReprocessLotDialog module", ()=> {
 it("commitReprocessingLot() should call controller.ok", ()=> {    
    let dialogController = {
          ok: (arg) = { }
        };

    spyOn(dialogController, "ok");

    let sut = new ReprocessLotDialog(dialogController);

    sut.commitIncompleteBags();
    expect(dialogController.ok).toHaveBeenCalled();
  });
});

You might also want to consider if testing if you shouldn't just be testing if commitReprocessingLot has been called instead of checking that it calls the method that's the only thing it does (at least in your example).

describe("The ReprocessLotDialog module", ()=> {
 it("commitReprocessingLot() should call controller.ok", ()=> {    
    let dialogController = {
          ok: (arg) = { }
        };

    let sut = new ReprocessLotDialog(dialogController);

    spyOn(sut, "commitReprocessingLot");

    sut.commitIncompleteBags();
    expect(su.commitReprocessingLot).toHaveBeenCalled();
  });
});
0
PW Kad On

You can definitely stub out the controller or you can just spy on the instance method like this -

describe("The ReprocessLotDialog module", ()=> {
    let container;
    let sut;
    let controller;

    beforeEach(()=> {
        container = new Container().makeGlobal();
        controller = container.get(DialogController);
        sut = container.get(ReprocessLotDialog);
    });


     it("commitReprocessingLot() should call controller.ok", (done)=> {    
        spyOn(controller, 'ok');
        sut.commitIncompleteBags();
        expect(controller.ok).toHaveBeenCalled();
        done();
    });
});

Basically you should be able to create an instance in your container of the controller that will get passed in and you can spyOn the method directly on the instance.