1

我一直在尝试将一个简单的后端连接到我的 Angular 应用程序,并决定使用 Firebase,因为在过去的应用程序中对它们有很好的体验。

当我在浏览器中加载该应用程序时,该应用程序会正确加载 Firebase,但是我遇到了通过 karma 单元测试失败的情况。

我已经为“设置”屏幕初始化了一个指令和一个控制器,允许您为您的应用设置自定义域名。

在最简单的形式中,它看起来像这样(参见完整源代码):

settingsController = function($scope, $element, $log, angularFire) {
    var domain = $scope.domain = "";
    var placeholder = $scope.placeholder = "e.g. www.strummer.io";
    console.log(angularFire);
    $scope.log = $log;
};

nav.directive('settings', function() {
    return {
        restrict: 'E',
        transclude: true,
        scope: { domain: '@' },
        controller: settingsController,
        templateUrl: 'static/nav/settings.html',
        replace: true
    };
});

在浏览器中加载时,我看到 angularFire 对象通过 console.log 命令显示。

但是,当我运行测试(通过 karma/jasmine)时,出现错误:

Error: Unknown provider: angularFireProvider <- angularFire
        at Error (<anonymous>)
        at /Users/dickason/code/strummer/builder/static/lib/angular.js:2696:15
        at Object.getService [as get] (/Users/dickason/code/strummer/builder/static/lib/angular.js:2824:39)
        at /Users/dickason/code/strummer/builder/static/lib/angular.js:2701:45
        at getService (/Users/dickason/code/strummer/builder/static/lib/angular.js:2824:39)
        at invoke (/Users/dickason/code/strummer/builder/static/lib/angular.js:2842:13)
        at Object.instantiate (/Users/dickason/code/strummer/builder/static/lib/angular.js:2874:23)
        at /Users/dickason/code/strummer/builder/static/lib/angular.js:4759:24
        at /Users/dickason/code/strummer/builder/static/lib/angular.js:4338:17
        at forEach (/Users/dickason/code/strummer/builder/static/lib/angular.js:138:20)
    Error: Declaration Location
        at window.jasmine.window.inject.angular.mock.inject (/Users/dickason/code/strummer/builder/static/lib/angular-mocks.js:1744:25)
    at null.<anonymous> (/Users/dickason/code/strummer/builder/static/nav/nav.spec.js:158:13)
    Error: Circular dependency:
        at Error (<anonymous>)
        at getService (/Users/dickason/code/strummer/builder/static/lib/angular.js:2817:17)
        at invoke (/Users/dickason/code/strummer/builder/static/lib/angular.js:2842:13)
        at Object.instantiate (/Users/dickason/code/strummer/builder/static/lib/angular.js:2874:23)
        at /Users/dickason/code/strummer/builder/static/lib/angular.js:4759:24
        at null.<anonymous> (/Users/dickason/code/strummer/builder/static/nav/nav.spec.js:170:20)
        at Object.invoke     (/Users/dickason/code/strummer/builder/static/lib/angular.js:2864:28)
        at workFn (/Users/dickason/code/strummer/builder/static/lib/angular-    mocks.js:1758:20)

这是有问题的测试设置(请参阅完整源代码):

describe("directive: settings", function() {
        var scope;

        // Setup DOM
        var html, element, compiled;
        beforeEach(function() {
            html = '' +
            '<settings></settings>' +

            inject(function($compile, $rootScope) {
                scope = $rootScope;
                element = angular.element(html);
                compiled = $compile(element)(scope);
                scope.$digest();
            });
        });


        // Setup Controller
        var ctrl;
        beforeEach(inject(function($controller) {
            ctrl = $controller('settingsController', {$scope: scope, $element: null});
        }));

        it("Should retrieve the domain from the datastore", inject(function($controller, $rootScope) {
            // Test Controller

        }));

经过一番谷歌搜索,我怀疑这与将 angularFire 注入控制器的方式有关。

我尝试了以下解决方案:

settingsController.$inject = ['$scope', '$element', '$log', 'angularFire'];

settingsController = ['$scope', '$element', '$log', 'angularFire', function($scope, $element, $log, angularFire) { ... }];

两者都给我留下了同样的错误。

任何建议,将不胜感激。

4

2 回答 2

3

通过一些试验和错误想通了。

当应用程序初始化时,firebase 与我的主模块('nav')一起被注入。

但是,在初始化测试时,由于某种原因,firebase 不会被注入。通过在每次测试之前手动将其作为模块注入,您可以避免“unknownProvider”错误。

代替:

beforeEach(module('nav'));

利用:

beforeEach(module('nav', 'firebase'));

采用这种方法,您可以在每个it('...')子句中在控制器中注入“angularFire”:

it("Should retrieve the domain from the datastore", inject(function($controller, $rootScope, angularFire) {
于 2013-09-11T22:41:24.743 回答
1

通常你会让 angularFire 在 nav.js 中注入到应用程序/模块中,如下所示:

var nav = angular.module('nav', ['angularFire']);

和你的设置控制器

settingsController = function($scope, $element, $log, angularFire) { }

将像注入 angularFire 一样注册到导航模块

nav.controller('settingsController', ['$scope', '$element', '$log', 'angularFire',
    function settingsController($scope, $element, $log, angularFire) {
        // Your code goes here
    }
]);

如果您将 settingsController 注册到 'nav' 应用程序而不是全局设置,然后将 angularFire 注入 'nav' 应用程序会怎样?

于 2013-09-11T03:00:06.893 回答