2015-02-25 35 views
8

Denetleyicimi oluşturmak için "denetleyici olarak" sözdizimini kullanıyorum. Varsayılan verileri yüklemek için bir işlevi çağıran özel bir başlatma işlevim var. Benim testteJasmine'i kullanarak bir denetleyici yöntemini nasıl uygularım?

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 
    var mc = this; 
    mc.dataLoaded = false; 

    function init() { 
    mc.loadData(); 
    } 

    mc.loadData = function(){ 
    mc.dataLoaded = true; 
    } 

    init(); 
}); 

Ben loadData işlev çağrılmış olup olmadığını kontrol etmek için bir casus yaratıyorum. Fonksiyonun, mc.dataLoaded bayrağı için test edilerek çağrıldığını doğrulayabilsem de, casusum çağrılan işlevi kaydetmiyor gibi görünüyor. İşlev çağrısını doğru bir şekilde kaydetmek için casusu nasıl alabilirim?

describe('Testing a Hello World controller', function() { 
    var $scope = null; 
    var ctrl = null; 

    //you need to indicate your module in a test 
    beforeEach(module('plunker')); 

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

    ctrl = $controller('MainCtrl as mc', { 
     $scope: $scope 
    }); 

    spyOn($scope.mc, 'loadData').and.callThrough(); 
    })); 

    it('should call load data', function() { 
    expect($scope.mc.loadData).toHaveBeenCalled(); 
    //expect($scope.mc.dataLoaded).toEqual(false); 
    }); 
}); 

Plunker link

cevap

9

Bu soyların dizisi:

ctrl = $controller('MainCtrl as mc', { 
    $scope: $scope 
}); 

spyOn($scope.mc, 'loadData').and.callThrough(); 

Yasemin casus denetleyicisi zaten $ kontrolörü tarafından örneği olmuştur sonra oluşturulur anlamına gelir. Casus oluşturulmadan önce, init işlevi zaten yürütüldü.

Çizgiler üzerinde casusluk yapmadan önce, MainCtrl'in bulunması gerektiğinden, satırları da değiştiremezsiniz.

init işlevi başka bir servisi çağırıyorsa, o hizmetin yöntemini görünüz ve hizmetin doğru çağrıldığını ileri sürün. Eğer MainCtrl sadece dahili bir şey yapıyorsa, bunun sonucunu test edin, örneğin, kontrolörün verilerinin/özelliklerinin güncellendiğini iddia ederek. Yeterince önemsiz ise test etmeye bile değmeyebilir. Ayrıca

, sen sözdizimi olarak denetleyici kullanıyorsanız beri, size $ denetleyicisi çağırarak yerine doğrudan kapsamını erişmenin dönüş değeri üzerinden kontrolörü başvurabilirsiniz:

ctrl = $controller('MainCtrl as mc', { 
    $scope: $scope 
}); 

ctrl.loadData === $scope.mc.loadData; // true 
+2

Soru belki de kapsam dışıdır ... $ kapsamı içinde olmayan bir işlevi gizlemek mümkün olabilir mi? Demek istediğim, bu kodda casusluk yapmam. –

+1

"Eğer MainCtrl sadece dahili bir şey yapıyorsa, bunun sonucunu, örneğin, denetleyicinin veri/özelliklerinin güncellendiğini iddia ederek test edin. Yeterince önemsiz olup olmadığını test etmeye bile değmeyebilir." BU GERÇEKTİR! –

+0

Ve iç denetleyici başlatma kodu başka bir hizmete güvenmiyor, sınama gerektirecek kadar karmaşık ve kapsam özelliklerinde hiçbir yan etkisi yok mu? Başlatma kodunu başka bir hizmete taşımak için tek seçeneğiniz var mı? Sadece ünite testlerini mümkün kılmak için kodunuzu daha karmaşık hale getirecek bir utanç gibi görünüyor. – d512

1

ben izin verilen bir çözüm buldu kontrol cihazımı değiştirmemek için. Ben Test Suite'in beforeEach yönteminde bir $state sahte hizmeti dahil ve buna bir reload sahte yöntem verdi:

beforeEach(inject(function ($controller, $rootScope) { 
    stateMock = { 
     reload: function() { 
      myCtrl = $controller('MyCtrl'); 
     } 
    }; 
    ... 

Sonra yasemin testler içinde, ben sadece benim casusları I korurken benim denetleyicisi yeniden başlatmak için stateMock.reload() çağırabilir başka bir beforeEach bloğunda bildirildi.

+0

Bu gerçekten çalışıyor mu? Yeni bir denetleyici nesnesi oluşturuyorsunuz, bu nedenle önceden eski denetleyici nesnesine atıldığınızı bildiren casuslar olmaz mı? – d512

+0

Ekibim için çalıştı. Beklenmedik değerlerde başarısızlığa uğratmak için Jasmine testlerini geçici olarak değiştirerek doğrulandı. Senin için hata mı attı? – dpfrakes

İlgili konular