2016-08-16 14 views
13

によってjasmineでテストされたコントローラでモジュールを利用できるようにするResharper 9.2を使用してPhantomJs経由でジャスミンを使用してコントローラを正常にテストできます。テストランナーとして。Resharper

私はhttps://blogs.endjin.com/2014/09/unit-testing-angularjs-with-visual-studio-resharper-and-teamcity/の指示に従ってResharperをセットアップしました。

これは働いていた:私はそれが依存するモジュールを指定いけない場合、私はコントローラのテストを実行することができます

コントローラー:

var moduleName; 
(function (moduleName) { 
    'use strict'; 
    var testableController = (function() { 
     function testableController($scope) { 
      var _this = this; 
      this.$scope = $scope; 

      $scope.title = "Welcome"; 
     } 
     testableController.className = 'testableController'; 
     return testableController; 
    }()); 
    moduleName.testableController = testableController; 
})(moduleName || (moduleName = {})); 

specファイルはこの

///<reference path="~/Scripts/jasmine/jasmine.js"/> 
///<reference path="~/Scripts/jasmine/angular.js"/> 
///<reference path="~/Scripts/jasmine/angular-mocks.js"/> 
///<reference path="~/Scripts/angular-ui/ui-bootstrap.min.js" /> 
///<reference path="~/Scripts/jasmine/controllers.js"/> 
///<reference path="~/Scripts/App/Controllers/testableController.js" /> 
///<reference path="~/Scripts/App/AppJasmine.js" /> 
describe("Controllers", function() { 

    beforeEach(module("moduleName")); 

    describe("Jasmine testableController", function() { 

     var scope, 
      controller; 

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

     it('should set the page title as "Welcome"', function() { 
      expect(scope.title).toBe('Welcome'); 
     }); 

    }); 
}); 
のように見えます

実コントローラは、角度uiブートストラップ "ui.bootstrap"を使用します。私は次のサンプルのように変更しますが、私はそれをテストしようとすると、エラーブートストラップ

angular.module('moduleName', ['ui.bootstrap']); 
var moduleName; 
(function (moduleName) { 
    'use strict'; 
    var testableController = (function() { 
     function testableController($scope, $uibModal) { 
      var _this = this; 
      this.$scope = $scope; 
      this.$uibModal = $uibModal; 
      $scope.title = "Welcome"; 
     } 
     testableController.className = 'testableController'; 
     return testableController; 
    }()); 
    moduleName.testableController = testableController; 
})(moduleName || (moduleName = {})); 

への依存関係を持つ

Error: [$injector:unpr] Unknown provider: $templateRequestProvider <- $templateRequest <- $uibModal 
http://errors.angularjs.org/1.2.24/$injector/unpr?p0=%24templateRequestProvider%20%3C-%20%24templateRequest%20%3C-%20%24uibModal in http://localhost:61032/referenceFile?path=~/webui/trunk/Netvacation.Pegasus.WebUI/Scripts/jasmine/angular.js (line 3802) 

コントローラー** EDIT 1 *がある場合、コントローラは、ページ上で動作します* 試しました

同じエラーがあります。

編集私が使用して2

http://angular-ui.github.io/bootstrap/ バージョン:1.3.3 - 2016年5月22日

AngularJSのv1.2.24

編集私がテストしたいいけない3 $ uibModal、でもそれを模倣する

+0

どのバージョンのui.bootstrapとどの角度の角度を使用していますか? – JayIsTooCommon

+0

アップデートされた質問ui.bootstrap 1.3.3、angular v1.2.24 –

答えて

0

私は2つの戦略を知っています複数の構文バリアントを持つサービスをAngularのすべてとして使用する...コントローラの宣言にオブジェクトリテラルを追加するだけで、サービスを独自に作成して$ providerを使用してモジュールに追加することができます。

サービスは、コントローラのコンストラクタに右場合は、オブジェクトリテラルで、その機能を模擬して注入することができ、いくつかのデータ層やAPIの単なるラッパーである、あなたのサンプル構文以下、これはちょうどこのように行うことができますで

var currentAuth; 

beforeEach(inject(function ($rootScope, $controller) { 
    scope = $rootScope.$new(); 
    currentAuth = {uid: 1, name: juan, getFriends: function() { ... }}; 

    controller = $controller('TestableCtrl', {'$scope': $scope, 'currentAuth': currentAuth }); 
})); 

このケースの「currentAuth」は、アプリケーションに現在ログインしているユーザーを提供するサービスです。

これは、オブジェクトに定義されている関数にサービスを挿入する必要がない場合にのみ有効です。それは、値サービスを作成してそれをモジュールに挿入するのと同等です。モックされたサービス内のメソッドがサービス自体を必要とする場合は、ファクトリまたはサービスを作成し、このサービスをモジュールに追加して、他のカスタムサービスと同様に注入する必要があります。私は、(これはクロームでのテストを必要とされない角度の約束を返すために$ qをサービスを使用して新工場を作成しています。このサンプルで

var $controller, $rootScope, $scope, $location, Auth; 

    beforeEach(function(){ 
    module('planner.login'); 

    module(function($provide){ 

     $provide.factory('Auth', function($q){ 
     return { 
      $signInWithEmailAndPassword: function(email, pass) { 
      return $q.reject({error: 'ERROR'}); 
      } 
     }; 
     }); 

     return null; 
    }); 

    }); 

    beforeEach(function(){ 

    inject(function($controller, $rootScope, _Auth_) { 
     $scope = $rootScope.$new(); 
     Auth = _Auth_; 

     $controller("TestableCtrl", { 
     $scope: $scope, 
     Auth: Auth, 
     $stateParams: {} 
     }); 
    }); 

    }); 

:私はangularfire認証サービスを模擬するために使用して、この例を参照してください。 PhantomJSにはPromise仕様がありません)。これにはbeforeEachが2つ必要です.1つはプロバイダをモジュールに追加し、もう1つはコントローラにプロバイダを注入することです。

どちらを使用するかは、テストする内容と元のサービス動作を模倣する必要があるかどうかによって異なります。あなたの場合、uibmodalを使うと、ある場所で'open 'を呼び出す必要があるかもしれませんが、呼び出されたスパイは必要ですが、そのプロパティを持つオブジェクトを作成し、そのオブジェクトプロパティをスパイする必要があります。だから最初のアプローチで十分でしょう。

だからあなたのコードのようなものでなければなりません。私はそれが役に立てば幸い

describe("Controllers", function() { 

    beforeEach(module("moduleName")); 

    describe("Jasmine testableController", function() { 

     var scope, 
      controller, 
      uibModal; 

     beforeEach(inject(function ($rootScope, $controller) { 
      scope = $rootScope.$new(); 
      uibModal = { open: function() { return 'Whatever'; } } 
      controller = $controller('testableController', { $scope: scope, $uibModal: uibModal }); 
     })); 

     it('should set the page title as "Welcome"', function() { 
      expect(scope.title).toBe('Welcome'); 
      // you will probably do something like this at some point to verify 
      // that the modal gets opened on click or following any other action: 
      // var spy = spyOn(uibModal, 'open'); 
      // expect(spy).toHaveBeenCalled(); 
     }); 

    }); 
}); 

、何かが明確でない場合、私はまた、AngularJSのアプリをテストについて学んでいますと、これはに役立つかどうかを知るのが大好きだ教えてくださいAngularUI。

0

最初の問題は、コントローラをモジュールに登録しないことです。したがって、モジュールの依存関係は認識していません。

angular.module('modulename').controller('nameofthecontroller', controller); 

$ uibModalをモックすることはできますが、必要はありません。このモックなしでうまくいくはずです。