mercredi 30 décembre 2015

Unit testing angular directive with injected custom services with Karma

I am trying to unit test a directive that has custom services injected into it. With controllers, I am able to do this successfully by creating mock objects and using the following code to instantiate the controller:

controller = $controller('AdminEditDeckCtrl', {$scope: scope, adminService: adminService, $state: state, notificationService: notificationService});

The mock services are injected properly and I can use Jasmine spies to assert that they are being called when they should be.

However, I am not able to instantiate a directive in the same way. I am trying to mock the services using $provide.service or $provide.value, but they don't seem to be being injected properly and Jasmine spies aren't working.

Here is a simplified test spec showing the setup for the test that is failing:

describe("Directive : Search Input", function() {
    var element, e, window, scope, controller, SearchService, userService, $stateParams;

    beforeEach(module("app"));
    beforeEach(module('src/templates/search-input.html'));
    beforeEach(module(function($provide) {
            userService = {
                    profile: {
                            name: 'Unit Test'
                    }
            };
            $stateParams = {
                    query: 'test'
            };
            SearchService = {
                    getSearchSuggestion: function() {
                            var deferred = q.defer();
                            deferred.resolve([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
                            return deferred.promise;
                    }
            };
            $provide.service('SearchService', function() {
                    return SearchService
            });
            $provide.value('userService', userService);
            $provide.value('$stateParams', $stateParams);
    }));
    beforeEach(inject(function($compile, $rootScope, _$window_) {
            scope = $rootScope.$new();
            window = _$window_;
            element = angular.element("<search-input></search-input>");
            $compile(element)(scope);
            scope.$digest();
            controller = element.controller("searchInput");
    }));

    it("getSearchChanges should call SearchService", function() {
            spyOn(SearchService, 'getSearchSuggestion').and.callThrough();
            element.scope().getSearchChanges();
            scope.$digest();
            expect(SearchService.getSearchSuggestion).toHaveBeenCalled();
    });
 });

The test is erroring with Expected spy getSearchSuggestion to have been called and it doesn't look like the mock SearchService is being called in the code (or at least the promise isn't returning that array of numbers)

Directive code can be seen here: http://ift.tt/1NQVKeG

Full test spec here:

http://ift.tt/1RRlyeC

Aucun commentaire:

Enregistrer un commentaire