简体   繁体   English

AngularJS测试,找不到我的控制器

[英]AngularJS test, can't find my controller

I met a problem with testing my controllers. 我在测试控制器时遇到问题。 I load them dynamically (lazy load, see after) so I wrote them like this : 我动态地加载它们(延迟加载,请稍后),所以我这样写它们:

angular.module('myApp').controllerProvider.register('DashboardCtrl', [
    '$scope', function ($scope) {
        $scope.foo = 'bar';
    }
]);

I initialise my module like this : 我这样初始化我的模块:

var app = angular.module('myApp', [
    'ngRoute',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router'
]);

app.run([
    '$rootScope', '$state', '$stateParams',
    function ($rootScope, $state, $stateParams) {
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
    }
]);

app.config(function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
    app.stateProvider = $stateProvider;
    app.routeProvider = $urlRouterProvider;
    app.controllerProvider = $controllerProvider;
    app.compileProvider = $compileProvider;
    app.filterProvider = $filterProvider;
    app.provide = $provide;

    $urlRouterProvider.otherwise('/');

    $stateProvider
        .state('dashboard', {
            url         : '/',
            templateUrl : 'views/dashboard.html',
            controller  : 'DashboardCtrl',
            resolve     : {
                deps : function ($q, $rootScope) {
                    var deferred = $q.defer();

                    curl('scripts/controllers/dashboard.js')
                        .then(function () {
                            $rootScope.$apply(function () {
                                deferred.resolve({});
                            });
                        });

                    return deferred.promise;
                }
            }
        });
});

That works. 这样可行。 Method is described there : http://ify.io/lazy-loading-in-angularjs/ 方法描述如下: http : //ify.io/lazy-loading-in-angularjs/

But when I want to test, I get each time the error : Error: [ng:areq] Argument 'DashboardCtrl' is not a function, got undefined 但是,当我要测试时,每次都会出现错误:错误:[ng:areq]参数'DashboardCtrl'不是一个函数,未定义

My test script : 我的测试脚本:

describe('Controller: DashboardCtrl', function () {
    'use strict';

    var DashboardCtrl,
        scope;

    // load the controller's module
    beforeEach(function () {
        var app = angular.module('cellierApp', [
            'ngRoute',
            'ngCookies',
            'ngResource',
            'ngSanitize',
            'ui.router'
        ]);

        app.run([
            '$rootScope', '$state', '$stateParams',
            function ($rootScope, $state, $stateParams) {
                $rootScope.$state = $state;
                $rootScope.$stateParams = $stateParams;
            }
        ]);

        app.config(function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
            app.stateProvider = $stateProvider;
            app.routeProvider = $urlRouterProvider;
            app.controllerProvider = $controllerProvider;
            app.compileProvider = $compileProvider;
            app.filterProvider = $filterProvider;
            app.provide = $provide;
        });

        inject(function ($controller, $rootScope) {
            scope = $rootScope.$new();
            DashboardCtrl = $controller('DashboardCtrl', {
                $scope : scope
            });
        });
    });

    it('should attach a list of awesomeThings to the scope', function () {
        expect(scope.foo).toBeDefined();
        expect(scope.foo).toBe('bar');
    });
});

I don't know what I'm doing wrong. 我不知道我在做什么错。 Is there someone who knows ? 有没有认识的人? Thanks in advance 提前致谢

I'm not sure whether Karma has support for Script.js loading, but for sure it has support for Require.js. 我不确定Karma是否支持Script.js加载,但是可以确定它是否支持Require.js。

Since you followed that tutorial, have you checked out the final example he gave on github (It contains unit testing as well)? 自从您遵循了该教程,您是否检查了他在github上给出的最后一个示例(它也包含单元测试)? The idea is that you can convert everything to use Require.js instead of Script.js and use Karma with karma-requirejs for the testing. 这个想法是,您可以将所有内容转换为使用Require.js而不是Script.js,并使用Karma和karma-requirejs进行测试。

Although it is not too difficult, there are quite a lot of changes. 尽管不太困难,但是有很多更改。 I won't post the working code here, but I would suggest reading the following: http://ify.io/unit-testing-lazily-loaded-angularjs-artefacts/ and http://karma-runner.github.io/0.8/plus/RequireJS.html 我不会在此处发布工作代码,但我建议阅读以下内容: http : //ify.io/unit-testing-lazily-loaded-angularjs-artefacts/http://karma-runner.github.io /0.8/plus/RequireJS.html

I can't link the final example because I don't have the reputation, but it's at the bottom of the tutorial you've linked. 我无法链接最后一个示例,因为我没有声誉,但这在您链接的教程的底部。

To see a runnable example using Asynchronous Module Definitions with RequireJS, have a look at the sample app." 要查看将异步模块定义与RequireJS一起使用的可运行示例,请查看示例应用程序。”

You don't load modules, but override the angular modules in this snippet: 您无需加载模块,但可以在此代码段中覆盖角度模块:

 var app = angular.module('cellierApp', [
    'ngRoute',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router'
  ]);

The proper call would be 正确的电话是

beforeEach(function() {
    // the module to be tested
    module('cellierApp');
});

Also, the var declaration of the app is very crappy imo. 另外,应用程序的var声明非常糟糕。 You have angular as a container, use it, don't create objects on global closure for no reason. 您有一个角容器,可以使用它,不要无缘无故地在全局闭包上创建对象。 Change this: 更改此:

var app = angular.module('myApp', [
    'ngRoute',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router'
]);

app.run...

To: 至:

angular.module('myApp', [
        'ngRoute',
        'ngCookies',
        'ngResource',
        'ngSanitize',
        'ui.router'
    ])
.config([...

.run([....

The unit test itself can be simplified so much: 单元测试本身可以简化很多:

describe('Controller: DashboardCtrl', function() {
    'use strict';

    var scope;

    // load the controller's module
    beforeEach(function() {
        module('cellierApp');
    });

    beforeEach(inject(function($controller, $rootScope) {
        scope = $rootScope.$new();
        $controller('DashboardCtrl', {
            $scope: scope
        });
    }));

    it('should attach a list of awesomeThings to the scope', function() {
        expect(scope.foo).toBeDefined();
        expect(scope.foo).toBe('bar');
    });
});

In your test you are not registering your controller 在测试中,您没有注册控制器

put your code for creating you controller in your test 将用于创建控制器的代码放入测试中

app.controllerProvider.register('DashboardCtrl', [
    '$scope', function ($scope) {
        $scope.foo = 'bar';
    }
]);

however depending on your test setup your app and controller files should be loaded through your test system and you should use 但是,根据您的测试设置,应通过测试系统加载应用程序和控制器文件,并应使用

beforeEach(module('cellierApp'));

instead of creating your app directly in your test 而不是直接在测试中创建应用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM