2016-10-25 17 views
2

私はこれが答えを見てきましたが、解決策のどれも私のために働いていません。私のテストが失敗する原因となっているエラーError: [ng:areq] Argument 'fn' is not a function, got undefinedが表示されます。スタブ付き工場ではないテスト仕様にファクトリを注入する正しい方法は何ですか?角度ユニットテスト工場インジェクション

ログインモジュール

angular.module('loginModule', ['ui.bootstrap', 'permission', 'ui.router', 'coreModule', 'utilsModule']); 

ログインコントローラ

(function(){ 
     'use strict'; 

     angular.module('loginModule') 
     .controller('loginController', login); 

     login.$inject = [ 
      '$log', 
      '$uibModal', 
      '$rootScope', 
      'storageFactory', 
      'loginFactory', 
      '$state', 
      'RoleStore', 
      'PermissionStore', 
      'vsmsCoreFactory' 
     ]; 

     function login($log, $uibModal, $rootScope, storageFactory, loginFactory, $state, RoleStore, PermissionStore, vsmsCoreFactory) { 

      /* jshint validthis: true */ 
      var vm = this; 
      vm.loginUser = loginUser; 
      vm.forgotPassword = forgotPassword; 
      vm.errorCode = null; 
      PermissionStore.clearStore(); 
      vsmsCoreFactory.getHashFunction() 
      .then(function(response) { 
       if(response) { 
        storageFactory.setHashFunction(response); // unknown provider 
       } 
      }); 

      function loginUser() { 
      ... 

ログインコントローラ仕様

describe('loginController', function() { 

    var $controller; 

    beforeEach(module('loginModule')); 

    beforeEach(inject(function(_$controller_){ 
    $controller = _$controller_; 
    })); 

    describe('vm.loginUser', function() { 
    it('should be defined', function() { 
     var loginController = $controller('loginController'); 
     expect(loginController.loginUser).toBeDefined(); 
    }); 
    }); 

}); 

ユニットテストファイル

'use strict'; 

var gulp = require('gulp'); 

var $ = require('gulp-load-plugins')(); 

var wiredep = require('wiredep'); 

var paths = gulp.paths; 

function runTests (singleRun, done) { 
    var bowerDeps = wiredep({ 
    directory: 'bower_components', 
    exclude: ['bootstrap-sass-official'], 
    dependencies: true, 
    devDependencies: true 
    }); 

    var testFiles = bowerDeps.js.concat([ 
    './src/components/scripts/ui-bootstrap-custom-tpls-2.1.3.js', 
    './src/app/index.js', 
    './src/{app,components}/**/*.module.js', 
    './src/{app,components}/**/*.factory.js', 
    './src/{app,components}/**/*.controller.js', 
    './src/{app,components}/**/*.spec.js' 
    ]); 

    gulp.src(testFiles) 
    .pipe($.karma({ 
     configFile: 'karma.conf.js', 
     action: (singleRun)? 'run': 'watch' 
    })) 
    .on('error', function (err) { 
     // Make sure failed tests cause gulp to exit non-zero 
     throw err; 
    }); 
} 

gulp.task('test', function (done) { runTests(true /* singleRun */, done) }); 
gulp.task('test:auto', function (done) { runTests(false /* singleRun */, done) }); 

アプリ

'use strict'; 

angular.module('fotaAdminPortal', 
    [ 
    'ngAnimate', 
    'ngCookies', 
    'ngTouch', 
    'ngSanitize', 
    'ngResource', 
    'ui.bootstrap', 
    'ui.router', 
    'ui.router.stateHelper', 
    'pascalprecht.translate', 
    'utilsModule', 
    'loginModule', 
    ... 
    ]) 

ログ

クローム54.0.2840する(Mac OS X 10.11.6)loginController vm.loginUserが失敗した エラーに定義する必要があります。[$インジェクター:UNPR]不明プロバイダ:storageFactoryProvider < - storageFactory < - loginController

答えて

1

fotaAdminPortalモジュールをテストのためにロードされていないので、vsmsCoreFactoryは登録されません。

また、手動でそれを作成するときに、インジェクタはこれを自動的に行いますようコントローラにサービスを渡す必要はありません。サービスを手動で渡すことは、グローバルに登録されたサービスでないもの、つまり$scopeを渡す必要がある場合や、単一のコントローラインスタンスに対してサービスをモックする場合に便利です。

気圧の工場のためのモックは、それらに依存するロジックが存在しないメソッドを呼び出そうとした場合にエラーが発生しますちょうど未定義の変数です。あなたは、これらのモック上の任意のメソッドを適切にスタブする必要があります。あなたが単独でloginModuleをロードする場合、あなたは別のモジュールにvsmsCoreFactoryを抽出し、依存関係としてそれを追加する必要が

describe('loginController', function() { 

    var $controller; 

    beforeEach(module('fotaAdminPortal')); 

    beforeEach(inject(function(_$controller_){ 
    $controller = _$controller_; 
    })); 

    describe('vm.loginUser', function() { 
     it('should be defined', function() { 
     var loginController = $controller('loginController'); 
     expect(loginController.loginUser).toBeDefined(); 
     }); 
    }); 

}); 

:しかし、一瞬のために取って、それらを残して、あなたのテストのようなものでなければなりません

angular.module('vsmsCore', []) 
    .factory('vsmsCoreFactory', function($http, env, $log, storageFactory) { 

    }); 

angular.module('loginModule', ['ui.bootstrap', 'permission', 'ui.router', 'vsmsCore']); 

そして、あなたの代わりに

+0

'fotaAdminPortal'あるカルマによってロードされるメインのアプリモジュール、(」./src/app/index.js『)と同様に、 'vsmsCoreFactory'(』 ./src beforeEach(module('loginModule'))を行うことができます/{app,components}/**/*.factory.js ')、単位テストファイル。カルマのログには、アプリファイルとファクトリの両方がロードされていることも表示されます。 'loginModule'は' fotaAdminPortal'の依存関係です。 – neridaj

+0

ファイルがロードされますが、モジュールを 'module(..) 'で起動しない限り、登録されません。問題は 'loginModule'は親モジュールからのサービス(' vsmsCoreFactory')に依存しているので密接に結合されており、単独では作成できません。アプリケーション全体を起動するか、サービスを別のモジュールに展開して、それを 'loginModule'への依存として追加してください。 – noj

+0

OKです。私は工場用の 'coreModule'を作成し、それを' loginModule'への依存として追加しました。これは 'vsmsCoreFactory'の問題を未定義に修正しました。今、私は未知のプロバイダ:storageFactoryProvider < - storageFactory < - loginControllerを見ています。 'storageFactory'は' utilsModule'に属しています。これは 'loginModule'の依存関係としても定義されています。 – neridaj

関連する問題