2014-09-02 75 views
1

爲長期職位提前道歉。過去幾天我一直堅持這一點。基本上,我有一個使用RequireJS設置的AngularJS項目,工作正常。我正在嘗試使用Angular,Require,Karma(Jasmine)組合編寫單元測試。錯誤我得到的是:AngularJS,RequireJS和Karma問題

Error: [ng:areq] Argument 'fn' is not a function, got Object 
http://errors.angularjs.org/1.2.9/ng/areq?p0=fn&p1=not%20a%20function%2C%20got%20Object 
at D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:78:12 
at assertArg (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:1363:11) 
at assertArgFn (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:1373:3) 
at annotate (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:3019:5) 
at invoke (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:3687:21) 
at Object.instantiate (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:3721:23) 
at D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:6772:28 
at null.<anonymous> (D:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:11:24) 
at Object.invoke (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:3710:17) 
at workFn (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular-mocks.js:2149:20) 
Error: Declaration Location 
at window.inject.angular.mock.inject (D:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular-mocks.js:2134:2 

at null.<anonymous> (D:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:9:20) 
at D:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:4:5 
.... 

這是文件夾結構:

ROOT 
|_app 
| |_js 
| | |_controllers 
| |   |_SimpleController.js 
| |_app.js, main.js 
| 
|_test 
|  |_spec 
|   |_mockApp.js 
|   |_TestAppSetupSpec.js 
| 
|__karma.conf.js 
|_ test-main.js 

以下是文件中的相關章節:

SimpleController.js:

define(["app"], function(app) { 

return angular.module("simpleApp").controller("SimpleController", ["$scope", 
    function($scope) { 
     $scope.msg = "Hello "; 
    } 
]); 
}); 

karma.conf.js

.... 
    // list of files/patterns to load in the browser 
files: [ 

    {pattern: 'app/lib/**/*.js', included: false}, 
    {pattern: 'app/js/controllers/*.js', included: false}, 
    {pattern: 'app/js/**/*.js', included: false}, 
    {pattern: 'app/js/services/*.js', included: false}, 
    {pattern: 'test/spec/*Spec.js', included: false}, 
    {pattern: 'test/spec/mockApp.js', included: false}, 
    'test-main.js', 
], 


// list of files to exclude 
exclude: [ 
    'app/js/main.js', 'app/js/app.js' ], 
.... 

測試main.js

var tests = []; 
for (var file in window.__karma__.files) { 
if (window.__karma__.files.hasOwnProperty(file)) { 
if (/Spec\.js$/.test(file)) { 
    tests.push(file); 
} 
} 
} 

require.config({ 
// Karma serves files under /base, which is the basePath from your config file 
baseUrl: '/base/app/js', 

paths: { 
    "angular" : "../lib/angular/angular", 
    "angular-resource" : "../lib/angular/angular-resource", 
    "angular-route" : "../lib/angular/angular-route", 
    "angular-storage" : "../lib/angular-local-storage", 
    "bootstrap-tooltip" : "../lib/bootstrap-tooltip", 
    "bootstrap-popover" : "../lib/bootstrap-popover", 
    "bootstrap" : "../lib/bootstrap.min", 
    "ui-bootstrap-tpls" : "../lib/ui-bootstrap-tpls-0.11.0", 
    "dirPagination" : "../lib/dirPagination", 
    "translate" : "../lib/angular-translate.min", 
    "translationsEN" : "../js/locale/en/translations_en", 
    "translationsDE" : "../js/locale/de/translations_de", 
    "jQuery" : "../lib/jquery-1.9.0", 
    "angular-mocks" : "../lib/angular/angular-mocks", 
    "app" : "../../test/spec/mockApp", 
    "SimpleController" : "controllers/SimpleController" 
}, 
shim: { 

    "jQuery" :{ 
     exports : 'jQuery' 
    }, 

    "angular" : { 
     deps: ["jQuery"], 
     exports: 'angular' 
    }, 


    "angular-resource": { 
      deps: ["angular"], 
      exports : 'ngResource' 
    }, 


    "app" : { 
     exports : 'app' 
    }, 

    "SimpleController" : { 
     deps : ["app"], 
     exports : 'SimpleController' 
    }, 


    "angular-mocks" : { 

     deps : ["angular"], 
     exports : 'angular-mocks' 
    }, 

    "angular-route": { 
     deps: ["angular"], 
     exports : 'ngRoute' 
    }, 
    "angular-storage": { 
     deps: ["angular"], 
     exports : 'angular-storage' 
    }, 
    "bootstrap": { 
    deps: ["jQuery"], 
     exports : 'bootstrap' 

    }, 
    "bootstrap-tooltip": { 
    exports : 'bootstrap-tooltip', 
    deps : ["jQuery"] 
    }, 
    "bootstrap-popover": { 
     exports : 'bootstrap-popover', 
     deps : ["jQuery"] 
    }, 

    "ui-bootstrap-tpls": { 
    deps : ["jQuery", "angular", "bootstrap", "bootstrap-tooltip", "bootstrap-popover"], 
    exports : 'ui-bootstrap-tpls' 
    }, 
    "dirPagination": { 
    deps : ["angular"], 
     exports : 'dirPagination' 
    }, 
    "translate": { 
    deps : ["angular", "translationsEN", "translationsDE"], 
     exports : 'translate' 
    } 

}, 
// dynamically load all test files 
deps: tests, 

// we have to kickoff jasmine, as it is asynchronous 
callback: window.__karma__.start 
}); 

mockApp.js:

define(["angular"], function(){ 
    var app = angular.module('simpleApp',[]); 
    return app; 

}); 

TestAppSetupSpec.js:

define([ 'angular', 'angular-mocks','SimpleController'], function (
    angular, angularMocks, SimpleController 
    ) { 
describe('App module tests', function() { 
    var module, $rootScope, scope, AppCtrl; 

    beforeEach(angular.module("simpleApp")); 

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

    })); 

    it("App Controller should be defined", function(){ 

     expect(AppCtrl).not.toBe(null); 
    }); 

}); 
}); 

我試圖用 「SampleController」 的建議,但現在我得到:

Chrome 37.0.2062 (Windows 7): Executed 2 of 2 (1 FAILED) (0.026 secs/0.023 secs) 
INFO [watcher]: Changed file "d:/workspace/ecart- oauth/src/main/webapp/test/spec/TestAppSetupSpec.js". 
Chrome 37.0.2062 (Windows 7) App module tests App Controller should be defined FAILED 
    TypeError: undefined is not a function 
    Error: [ng:areq] Argument 'SimpleController' is not a function, got undefined 
    http://errors.angularjs.org/1.2.9/ng/areq? p0=SimpleController&p1=not%20a%20function%2C%20got%20undefined 
     at d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:78:12 
     at assertArg (d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:1363:11) 
     at assertArgFn (d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:1373:3) 
     at d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:6769:9 
     at null.<anonymous> (d:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:12:26) 
     at Object.invoke (d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular.js:3710:17) 
     at workFn (d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular-mocks.js:2149:20) 
    Error: Declaration Location 
     at window.inject.angular.mock.inject (d:/workspace/ecart-oauth/src/main/webapp/app/lib/angular/angular-mocks.js:2134:2 
5) 
     at null.<anonymous> (d:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:9:20) 
     at d:/workspace/ecart-oauth/src/main/webapp/test/spec/TestAppSetupSpec.js:4:5 

我錯過了什麼? 任何幫助,非常感謝。

回答

1

我終於得到了這個工作 - 但對於我的生活,我仍然不明白爲什麼它可以工作,即使我有一個微弱的想法。發佈它爲未來任何迷失的靈魂。

我不得不寫的SimpleController,如:

define(["app"], function(app) { 

var SimpleController = 
    function($scope) { 
     $scope.sayHello = function() { 
      return "Hello"; 
     } 
    } 


SimpleController.$inject = ['$scope']; 


app.controller('SimpleController', SimpleController); 

return SimpleController; //NOTE: not returning app.controller(..) which returns an object. 
}); 

測試用例現在看起來像:

define([ 'angular', 'angular-mocks', 'controllers/SimpleController'], function (
    angular, angularMocks, SimpleController 
    ) { 
describe('App module tests -->', function() { 
    var scope, SimpleCtrl; 


    beforeEach(
      function(){ 
      angular.module("simpleApp"); 
      } 

    ); 

    beforeEach(inject(function($rootScope, $controller){ 

     scope = $rootScope.$new(); 

     SimpleCtrl = $controller(SimpleController, { 
      '$scope': scope 
     }); 
    }) 

    ); 

    it("App Controller should be defined", function(){ 

     expect(SimpleCtrl).not.toBe(null); 
    }); 

    it("The controller should have a sayHello method that says Hello", function(){ 

     expect(scope.sayHello).toMatch('Hello'); 

    }); 

}); 
}); 

而且,不需要爲SimpleController路徑或墊片聲明。它使用'controllers/SimpleController'在測試類中查找 - 文件駐留在'app/controllers'子文件夾中。

0

你已經混了一點東西:

SimpleController.js(我猜上面SampleController.js是一個錯字)返回名爲角模塊"simpleApp"(這是一個對象)。在這個模塊中,有一個名爲"SimpleController"的控制器。在測試腳本的正確用法是:

AppCtrl = $controller("SimpleController", { // NOTE THE QUOTES!!! 
    '$scope': scope 
}); 

這就是爲什麼角被抱怨的對象,發現其中一個功能預期。

+0

HI尼科斯,我試過你的建議,但這次得到一個新的錯誤。我已更新原始帖子。 – trishulpani 2014-09-02 12:17:08

+0

看來控制器沒有註冊。你能確保Angular被引導(打印一條消息或其他東西)嗎?另外docs說:「inject()'創建每個測試的$注入器的新實例」([ref](https://docs.angularjs.org/api/ngMock/function/angular.mock.inject))。是否Angular在第二次測試中沒有正確初始化?我有同樣的問題[這裏](https://github.com/nikospara/angular-require-lazy/blob/karma/WebContent/scripts/app/modules/categories/categoryDirective.spec.js) - 請參閱' XXX'評論。要解決這個問題,請保留並重新使用原始噴油器。 – 2014-09-02 14:17:09

+0

嗨尼科斯,我感謝您的回覆。然而,我不知道該把信息放在哪裏(我知道我聽起來很愚蠢 - 但忍耐着我 - 這是新的)。此外,如果您可以更具體地瞭解如何保留和重複使用原始噴油器 - 那會很棒。萬分感謝 ! – trishulpani 2014-09-03 05:37:43