Angularjs вводил пустой контроллер при тестировании с Jasmine

В настоящее время я работаю с Angular и использую Karma и Jasmine для тестирования. Фильтры, например, внедряются в основной модуль и могут быть протестированы без каких-либо проблем, но когда я пытаюсь протестировать контроллеры, после внедрения я получаю пустой объект.

Вот код моего основного модуля:

(function () {

    'use strict';

    var dependencies = [];

    angular.module('myApp', dependencies)

}());

Контроллер, который я должен проверить:

(function () {
    'use strict';

    angular.module('myApp')

        .controller('NavCtrl', ['$scope',
            function ($scope) {

                $scope.currentUser = null;

            }]);
}());

И, наконец, набор тестов:

describe ("controller", function() {

    beforeEach(module("myApp"));

    var $scope, $rootScope, controllerLoader;

    beforeEach(inject(function($injector) {
        $rootScope = $injector.get('$rootScope');
        $scope = $rootScope.$new();

        var $controller = $injector.get('$controller');

        controllerLoader = function() {
            return $controller('NavCtrl', {
                '$scope': $scope
            });
        };
    }));

    it ("testing injection", function() {

        var controller = controllerLoader();
        expect(controller).toNotEqual({});

    })

});

Но результат теста FAIL, и после отладки я вижу, что инжектированный контроллер пуст. Я уже пытался дать ложное имя для контроллера и тест просто вылетает, что означает, что контроллер обнаружен, но по какой-то причине я не получаю его свойства.


person Eduardo Páez Rubio    schedule 25.03.2014    source источник
comment
Попробуйте переместить var $controller = $injector.get('$controller'); внутрь функции controllerLoader.   -  person Davin Tryon    schedule 25.03.2014
comment
зачем тебе доступ к контроллеру? в тестовом примере у вас уже есть доступ к $scope   -  person doodeec    schedule 25.03.2014
comment
Это сработало, я не знал, как правильно получить доступ к контроллеру. Очевидно, дважды подумав, я должен сделать это через $scope. Спасибо большое!   -  person Eduardo Páez Rubio    schedule 25.03.2014
comment
как ты это решил? я новичок в karma/jasmine/angularjs... тоже сталкиваюсь с этой проблемой, но не понимаю почему...   -  person rcheuk    schedule 13.02.2015
comment
проверьте комментарий @doodeec   -  person Eduardo Páez Rubio    schedule 17.02.2015


Ответы (1)


У меня была аналогичная проблема. Разница в том, что в своем приложении я использую RequireJS, поэтому некоторые части немного отличаются, но я думаю, что в целом это может вам помочь.

Я изменил его, чтобы он соответствовал вашим именам:

define(['app/app.module', 'angular', 'angular-mocks'], function () {

  describe('Controller Unit test', function () {

    var $controller;

    beforeEach(module('myApp'));

    beforeEach(inject(function (_$controller_) {
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $controller = _$controller_;
    }));

    describe('Get the controller', function () {
        it('should contain controller', function () {
            var $scope = {};
            var controller = $controller('NavCtrl', {$scope: $scope});

            console.log(controller);
            expect(controller).toBeDefined();
        });
    });
  });
});

Очень важно загружать как angular, так и angular-mocks. Однако я думаю, что основная проблема заключается в том, что ваша функция controllerLoader находится в разделе beforeEach. Инъекция должна быть сделана в разделе describe самого теста.

person Atais    schedule 18.08.2015