8

$rootScope.$broadcast('myApiPlay', { action : 'play' });'un çağrıldığını doğrulayan bir birim testi yazmaya çalışıyorum. İşte

myapi.js

angular.module('myApp').factory('MyApi', function ($rootScope) { 
    var api = {}; 
    api.play = function() { 
     $rootScope.$broadcast('myApiPlay', { action : 'play' }); 
    } 
    return api; 
}); 

Ve burada benim Birim Test: İşte

describe('Service: MyApi', function() { 

    // load the service's module 
    beforeEach(module('myApp')); 

    // instantiate service 
    var MyApi; 
    var rootScope; 

    beforeEach(function() { 
     inject(function ($rootScope, _MyApi_) { 
      MyApi = _MyApi_; 
      rootScope = $rootScope.$new(); 
     }) 
    }); 
    it('should broadcast to play', function() { 
     spyOn(rootScope, '$broadcast').andCallThrough(); 
     rootScope.$on('myApiPlay', function (event, data) { 
      expect(data.action).toBe('play'); 
     }); 
     MyApi.play(); 
     expect(rootScope.$broadcast).toHaveBeenCalledWith('myApiPlay'); 
    }); 
}); 

grunt test çalıştırırken i alıyorum hatadır:

PhantomJS 1.9.7 (Windows 7) Service: MyApi should broadcast to pause FAILED 
     Expected spy $broadcast to have been called with [ 'myApiPlay' ] but it was never called. 

expect(rootScope.$broadcast).toHaveBeenCalled() ile de denedim ve benzer bir hata yaşıyorum: Expected spy $broadcast to have been called..

Bu yöntemin gerçekten doğru parametrelerle çağrıldığını doğrulamak istiyorum.

Teşekkür ederiz!

+0

sadece sıralamasını değiştirmek gerekir mi? Aslında çağrılmadan önce beklemeniz gerekebilir, sizin durumunuzda, bunu bekleyiniz. Ayrıca, çağrı sayısını doğrulayabilirsiniz. – hassassin

+0

Siparişi değiştirdim, aynı hata. – Andrea

cevap

14

. BeforeEach kurulumunuzda, $ rootScope'un enjekte edilmesini istersiniz ve sonra $ rootScope'u arayarak bir çocuk kapsamı yaratırsınız. $ New().

$ rootScope öğesinden dönüş değeri. $ New() artık rootScope değil, kök kapsamı alt öğesidir. Playlistinde fonksiyonunda

beforeEach(function() { 
    //inject $rootScope 
    inject(function ($rootScope, _MyApi_) { 
     MyApi = _MyApi_; 
     //create a new child scope and call it root scope 
     rootScope = $rootScope.$new(); 
     //instead don't create a child scope and keep a reference to the actual rootScope 
     rootScope = $rootScope; 
    }) 
}); 

, size $ rootScope üzerinde $ yayını aradığınız ancak test Eğer $ rootScope çocuğu gözetliyorsun.
$rootScope.$broadcast('myApiPlay', { action : 'play' }); 

Yani, bunu tamamlamayı $ rootScope çağrısı kaldırın. Yeni $() ve sadece enjektör size verdiği $ rootScope gözetlemek için. Birim testinize sağlanan $ rootScope, API hizmetinize sağlanan aynı $ rootScope'dur ve bu nedenle doğrudan $ rootScope üzerinde casusluk yapmalısınız.

Kontrol dışarı plunkr http://plnkr.co/edit/wN0m8no2FlKf3BZKjC4k?p=preview

+2

bu bekleyiş (rootScope. $ Broadcast) .toHaveBeenCalledWith ('myApiPlay', {action: 'play'}); 'ancak bu bekleyiş çağrılmadı: rootScope. $ On (' myApiPlay ', function (event) , data) {expect (data.action) .toBe ('play');}); ' – Andrea

+1

bu sınava ihtiyacınız yok. Bu test, iş mantığının kendisi değil, açısal çerçeveyi test ediyor. RootScope. $ Yayınını çağırdığınızda, $ on kullanarak dinleyicilerin kurulumunun doğru olarak çağrılacağını varsayabilirsiniz, çünkü AngularJS'nin – jcruz

+0

gerçekten test etmeniz gereken tek şey bu kadar $ rootScope olmasıdır.Beklenen parametreler – jcruz

1

Sizin için faydalı olacaktır. https://stackoverflow.com/a/17227264/2594499 Testiniz net değil. Koşullarda, geri aramalarda ve benzeri şeylerde "beklemeyi" kullanmaktan kaçının. Durumunuz doğru olmazsa, onaylamadan test yaptırırsınız.

fonksiyonun ikinci parametresi kullanmak daha iyi olacak: Yanlış $ yayın fonksiyonu gözetliyorsun çünkü testler geçmezken nedenidir

.toHaveBeenCalledwith('someEvent', someObj); 
+0

Merhaba, söylediğin gibi yapıyorum, ama birim testi buna çağrılmadığını söylüyor. 'MyApi.play()' çağrılırken mesajın yayınlandığını test ediyorum. – Andrea

İlgili konular