AngularJS Unit Testing Controller w/ service dependency in Jasmine

bobbyz

I'm brand new to testing, and I've been trying to find the best strategy for unit testing an AngularJS controller with a service dependency. Here's the source code:

app.service("StringService", function() {
    this.addExcitement = function (str) {
        return str + "!!!";
    };
});

app.controller("TestStrategyController", ["$scope", "StringService", function ($scope, StringService) {
    $scope.addExcitement = function (str) {
        $scope.excitingString = StringService.addExcitement(str);
    };
}]);

And the test I'm using currently:

describe("Test Strategy Controller Suite", function () {
    beforeEach(module("ControllerTest"));

    var $scope, MockStringService;

    beforeEach(inject(function ($rootScope, $controller) {
        $scope = $rootScope.$new();
        MockStringService = jasmine.createSpyObj("StringService", ["addExcitement"]);
        $controller("TestStrategyController", {$scope: $scope, StringService: MockStringService});
    }));

    it("should call the StringService.addExcitement method", function () {
        var boringString = "Sup";
        $scope.addExcitement(boringString);
        expect(MockStringService.addExcitement).toHaveBeenCalled();
    });
});

This test passes, but I'm confused about something: if I change the name of the method in the service (let's say I call it addExclamations instead of addExcitement but not where it is used in the controller (still says $scope.excitingString = StringService.addExcitement(str);), my tests still pass even though my controller is now broken. However, once I change the method name in the controller as well, so as to fix the actual breakage caused by changing the service's method name, my tests break because it's trying to call the old addExcitement method.

This would indicate that I would need to manually keep the method names in sync with the service by changing the jasmine spy object line to MockStringService = jasmine.createSpyObj("StringService", ["addExclamations"]);.

All of this seems backwards to me, since I feel like my test should break when I change the service's method name without changing how the controller references that service name. But I'm not sure how to get the best of both worlds here, because if I'm expecting my test to keep track of that service name somehow, there's no way for it to pass again when I change the method name in both the service and the controller because the spyObj still has the old name.

Any insight or advice about the strategy behind this would be greatly appreciated. I'm going to be teaching this to some students, and am mostly trying to make sure I'm following best practices with this.

sdfacre

I'd say that's the expected result of the way your test code works, simply because you created a "brand new" mock service object. I guess you know what I am talking about.

What I usually do is get the service instance and mock the method, instead of creating a completely new mock object.

   beforeEach(inject(function ($rootScope, $controller, $injector) {
       $scope = $rootScope.$new();
       MockStringService = $injector.get('StringService'); 
       spyOn(MockStringService , 'addExcitement').andReturn('test');
       $controller("TestStrategyController", {$scope: $scope, StringService: MockStringService});
   }));

please note that andReturn() is a jasmine 1.x method, depends on the version you are using, you may want to change the code a little bit.

Having it this way, if you change the method name in StringService, you should get errors from spyOn() method, as the method doesn't not exist any more.

Another thing is that, you don't have to use $injector as I did to get the service instance, you can just inject your service instead in fact. I don't recall why I did it this way. :)

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

mock angularjs service for unit testing using jasmine

From Dev

Angularjs Unit Test Not Hitting then part of controller after calling service in AngularJS & testing using Karma & Jasmine

From Dev

Angularjs Unit Test Not Hitting then part of controller after calling service in AngularJS & testing using Karma & Jasmine

From Dev

AngularJS and QUnit: Testing Controller with Service Dependency

From Dev

Difficulty in testing Angularjs controller with service as its dependency

From Dev

Unit testing Angularjs jasmine

From Dev

AngularJS Jasmine Unit Testing - Controller method is never called

From Dev

AngularJS Jasmine Unit Testing - Controller method is never called

From Dev

Angularjs and Jasmine: Testing a controller with a service making ajax call

From Dev

expect() in .then() - jasmine unit testing, AngularJS

From Dev

Unit test inject dependency like controller for service in angularJS

From Dev

Unit Testing AngularJS Service

From Dev

Unit testing a service in angularJS

From Dev

AngularJS controller unit test with Jasmine

From Dev

AngularJS: Unit Testing Directive w/ Promise returned from a Service

From Dev

AngularJS: Unit Testing Directive w/ Promise returned from a Service

From Dev

Testing AngularJS controller /w karma-jasmine: 'jasmine.clock().mockDate(baseTime)' undefined

From Dev

Unit testing a modalInstance controller with Karma / Jasmine

From Dev

Jasmine Angular unit testing: controller with an external variable

From Dev

Unit testing an angular service method in jasmine

From Dev

Unit Testing an Angular Service using Karma and Jasmine

From Dev

Unit-Testing a filter with Jasmine in AngularJS

From Dev

Unit-testing slider directive with AngularJS + Jasmine

From Dev

Unit-Testing a filter with Jasmine in AngularJS

From Dev

Unit testing of Services / Factories - AngularJS - Jasmine

From Dev

ReferenceError : AngularJS is not defined on Karma with Jasmine unit testing

From Dev

Unit Testing AngularJS and PouchDB Service

From Dev

Unit testing the AngularJS $window service

From Dev

Angularjs unit testing service with promise

Related Related

  1. 1

    mock angularjs service for unit testing using jasmine

  2. 2

    Angularjs Unit Test Not Hitting then part of controller after calling service in AngularJS & testing using Karma & Jasmine

  3. 3

    Angularjs Unit Test Not Hitting then part of controller after calling service in AngularJS & testing using Karma & Jasmine

  4. 4

    AngularJS and QUnit: Testing Controller with Service Dependency

  5. 5

    Difficulty in testing Angularjs controller with service as its dependency

  6. 6

    Unit testing Angularjs jasmine

  7. 7

    AngularJS Jasmine Unit Testing - Controller method is never called

  8. 8

    AngularJS Jasmine Unit Testing - Controller method is never called

  9. 9

    Angularjs and Jasmine: Testing a controller with a service making ajax call

  10. 10

    expect() in .then() - jasmine unit testing, AngularJS

  11. 11

    Unit test inject dependency like controller for service in angularJS

  12. 12

    Unit Testing AngularJS Service

  13. 13

    Unit testing a service in angularJS

  14. 14

    AngularJS controller unit test with Jasmine

  15. 15

    AngularJS: Unit Testing Directive w/ Promise returned from a Service

  16. 16

    AngularJS: Unit Testing Directive w/ Promise returned from a Service

  17. 17

    Testing AngularJS controller /w karma-jasmine: 'jasmine.clock().mockDate(baseTime)' undefined

  18. 18

    Unit testing a modalInstance controller with Karma / Jasmine

  19. 19

    Jasmine Angular unit testing: controller with an external variable

  20. 20

    Unit testing an angular service method in jasmine

  21. 21

    Unit Testing an Angular Service using Karma and Jasmine

  22. 22

    Unit-Testing a filter with Jasmine in AngularJS

  23. 23

    Unit-testing slider directive with AngularJS + Jasmine

  24. 24

    Unit-Testing a filter with Jasmine in AngularJS

  25. 25

    Unit testing of Services / Factories - AngularJS - Jasmine

  26. 26

    ReferenceError : AngularJS is not defined on Karma with Jasmine unit testing

  27. 27

    Unit Testing AngularJS and PouchDB Service

  28. 28

    Unit testing the AngularJS $window service

  29. 29

    Angularjs unit testing service with promise

HotTag

Archive