2012-09-18 6 views
10

ネストされたコントローラのユニットテストを作成しようとしていますが、テストで同じ動作をどのように模擬するかわかりません。ネストされたコントローラのユニットテスト

私は2つのコントローラがあります。

function FirstController ($scope) { 
    $scope.childs = [{ 
     title : 'Hello, earth!' 
    }]; 
}; 

function SecondController ($scope) { 
    $scope.child.title = $scope.child.title + $scope.$index; 
}; 

そして、私のHTMLで:

<div data-ng-controller="FirstController"> 
    <div data-ng-repeat="child in childs" data-ng-controller="SecondController"> 
     {{ child.title }} 
    </div> 
</div> 

そして予想通り、この作品(http://jsfiddle.net/tcayp/1/

ユニットテスト:

// FirstController 
it('Should have childs', function() { 
    scope = {}; 
    ctrl = new FirstController(scope); 
    expect(scope.childs.length).toBeGreaterThan(0); 
}); 
// SecondController 
it('Should have inherited a child', function() { 
    scope = {}; 
    ctrl = new SecondController(scope); 
    expect(scope.child.title).toEqual('Hello, earth!0'); 
}); 

をにSecondController-test継承したチェーンをng-repeatからどうやって模倣するのか分かりません。

答えて

16

理想的には、ユニットテストでは、クラス(ユニット)を単独でテストしたいと考えています。 1つのテストで2つのコントローラをテストするのは多すぎるかもしれません。テストはより複雑で脆くなります。

提供されている例を詳しく見てみると、2つのコントローラをテストするのではなく、親スコープでデータを利用できることを確認することができます。だから、1つののみのコントローラ(SecondController)、もう1つは、このようなテストを書くと継承されたデータに焦点を当て:ここ

describe('Testing the SecondController controller', function() { 

    var $parentScope, $scope, ctrl; 
    it('should prepare title', inject(function($rootScope, $controller) { 

     //setup hierarchy of scopes with data    
     $rootScope.childs = [{ 
      title : 'Hello, earth!' 
     }]; 
     $scope = $rootScope.$new(); 
     $scope.$index = 1; 

     ctrl = $controller('SecondController', { 
      $scope: $scope 
     }); 

     expect($scope.childs[0].title).toEqual('Hello, earth!1');   
    })); 
}); 

すると、フルjsFiddleです:http://jsfiddle.net/pkozlowski_opensource/h8xry/13/

私は本当にテストに対して2つのコントローラを一緒に助言するだろうが、ただ、質問に答えるために、それは同様に可能である:

describe('Testing the SecondController controller', function() { 

    it('should prepare title', inject(function($rootScope, $controller) { 

     $controller('FirstController', { 
      $scope: $rootScope 
     }); 

     var $scope = $rootScope.$new(); 
     $scope.$index = 1; 

     ctrl = $controller('SecondController', { 
      $scope: $scope 
     }); 

     expect($scope.childs[0].title).toEqual('Hello, earth!1');   
    })); 
}); 

そしてjsFiddle:http://jsfiddle.net/pkozlowski_opensource/4Qy6b/1/

+0

ありがとう、私はあなたの最初の例を使用するように書き直しました。 – fredrik

2

AngularJS documentationは、ネストされたコントローラをそれぞれインスタンス化し、アプリケーションと同じスコープ階層を確立することによって、ネストされたコントローラをテストすることを提案しています。これは理にかなっています。現実的な状況でコントローラをテストしたいからです。 AngularJS documentationから

childScope = mainScope.$new(); 
$controller('ChildController', {$scope: childScope}); 

例:以前にインスタンス化されたスコープを使用して、新しいスコープをインスタンス化し、

mainScope = $rootScope.$new(); 
$controller('ParentController', {$scope: mainScope}); 

とあなたの子供のコントローラで:あなたの試験で

1

は、新しいスコープで親コントローラをインスタンス化:

describe('state', function() { 

    var mainScope, childScope, grandChildScope; 

    beforeEach(module('myApp')); 

    beforeEach(inject(function($rootScope, $controller) { 
     mainScope = $rootScope.$new(); 
     $controller('MainController', {$scope: mainScope}); 
     childScope = mainScope.$new(); 
     $controller('ChildController', {$scope: childScope}); 
     grandChildScope = childScope.$new(); 
     $controller('GrandChildController', {$scope: grandChildScope}); 
    })); 

    it('should have over and selected', function() { 
     expect(mainScope.timeOfDay).toBe('morning'); 
     expect(mainScope.name).toBe('Nikki'); 
     expect(childScope.timeOfDay).toBe('morning'); 
     expect(childScope.name).toBe('Mattie'); 
     expect(grandChildScope.timeOfDay).toBe('evening'); 
     expect(grandChildScope.name).toBe('Gingerbread Baby'); 
    }); 
}); 
関連する問題