admin管理员组

文章数量:1400599

Getting started with HotTowelAngular template and I'm setting up unit testing. Ran into a snag.

I'm trying to test a function in my controller that happens to call another function named "log". This "log" is a function stored in a private variable which gets its value from a dependency called "mon".

I'm aware that I probably need to stub this function in some way, but I'm unsure of where to start for this particular example, as I'm pretty new to angularjs, jasmine, et all. Any ideas are appreciated

unit test:

describe("quote", function () {
    var scope,
        controller,
        mon;

    beforeEach(inject(function($rootScope, $controller, _mon_) {
        scope = $rootScope.$new();
        mon = _mon_;
        controller = $controller;
    }));

 describe("removeAttachment", function() {

        it("should remove the attachment when requested", function() {
            var vm = controller("quote", { $scope: scope });

            vm.attachmentList.push({ FileName: "file1", FileAsString: "..." });
            vm.attachmentList.push({ FileName: "file2", FileAsString: "..." });
            vm.attachmentList.push({ FileName: "file3", FileAsString: "..." });
            expect(vm.attachmentList.length).toEqual(3);

            // here's the call where it fails
            vm.removeAttachment(vm.attachmentList[1]);

            expect(vm.attachmentListCount).toEqual(2);
            expect(vm.attachmentList.length).toEqual(2);
            expect(vm.attachmentList[1].FileName).toBe("file3");
        });
    });
 });

controller:

 var getLogFn = mon.logger.getLogFn;
 var log = getLogFn(controllerId);

 function removeAttachment(attachment) {

        // need to stub this out
        log('removing attachment: ' + attachment.FileName);

        vm.attachmentList.splice(vm.attachmentList.indexOf(attachment), 1);
        vm.attachmentListCount = vm.attachmentList.length;
    }

The error from Jasmine:

TypeError: 'undefined' is not a function (evaluating 'log('removing attachment: ' + attachment.FileName)')

Getting started with HotTowelAngular template and I'm setting up unit testing. Ran into a snag.

I'm trying to test a function in my controller that happens to call another function named "log". This "log" is a function stored in a private variable which gets its value from a dependency called "mon".

I'm aware that I probably need to stub this function in some way, but I'm unsure of where to start for this particular example, as I'm pretty new to angularjs, jasmine, et all. Any ideas are appreciated

unit test:

describe("quote", function () {
    var scope,
        controller,
        mon;

    beforeEach(inject(function($rootScope, $controller, _mon_) {
        scope = $rootScope.$new();
        mon = _mon_;
        controller = $controller;
    }));

 describe("removeAttachment", function() {

        it("should remove the attachment when requested", function() {
            var vm = controller("quote", { $scope: scope });

            vm.attachmentList.push({ FileName: "file1", FileAsString: "..." });
            vm.attachmentList.push({ FileName: "file2", FileAsString: "..." });
            vm.attachmentList.push({ FileName: "file3", FileAsString: "..." });
            expect(vm.attachmentList.length).toEqual(3);

            // here's the call where it fails
            vm.removeAttachment(vm.attachmentList[1]);

            expect(vm.attachmentListCount).toEqual(2);
            expect(vm.attachmentList.length).toEqual(2);
            expect(vm.attachmentList[1].FileName).toBe("file3");
        });
    });
 });

controller:

 var getLogFn = mon.logger.getLogFn;
 var log = getLogFn(controllerId);

 function removeAttachment(attachment) {

        // need to stub this out
        log('removing attachment: ' + attachment.FileName);

        vm.attachmentList.splice(vm.attachmentList.indexOf(attachment), 1);
        vm.attachmentListCount = vm.attachmentList.length;
    }

The error from Jasmine:

TypeError: 'undefined' is not a function (evaluating 'log('removing attachment: ' + attachment.FileName)')

Share Improve this question asked Aug 26, 2014 at 15:01 proggrockproggrock 3,2997 gold badges38 silver badges51 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 5

In your test you should have controller = $contoller("YourController", {it's dependencies});

You probably don't want to pass in your mon service, but create a stub that returns a function.

var  wrapper = {logger: function () {}};
var stub = { logger: { getLogFun: function() {return wrapper.logger} }};

You can pass that in place of your mon service.

You can now spy on it with:

spyOn(wrapper, 'logger');

Is var log = getLogFn(controllerId) being called before removeAttachment? Is getLogFn() injected into the controller? If these are both true, you could stub out getLogFn() to return a dummy log object that you could use for testing. I am not aware of hottowel, I use Sinon. In Sinon, I would call

var getLogFnStub = sinon.stub().returns(function (msg) { return 1;/*My expected result*/ });

and pass that into your controller, like

var vm = controller("quote", { $scope: scope, getLogFn: getLogFnStub});

If you wanted, you could then do asserts against the stub you made in Sinon, like so

sinon.assert.called(getLogFnStub);

本文标签: javascriptmock a function call using jasmineStack Overflow