2013-04-15 16 views
7

Próbowałem przetestować usługę bezskutecznie od jakiegoś czasu i miałem nadzieję na jakąś pomoc. Oto moja sytuacja:Serwis wstrzykiwania AngularJS przedrukuje w testach serwisowych

mam serwis patrząc trochę jak ten

myModule.factory('myService', ['$rootScope', '$routeParams', '$location', function($rootScope, $routeParams, $location) { 

    var mySvc = { 
    params: {} 
    } 

    // Listen to route changes. 
    $rootScope.$on('$routeUpdate', mySvc.updateHandler); 

    // Update @params when route changes 
    mySvc.updateHandler = function(){ ... }; 

    ... 
    ... 

    return mySvc; 

}]); 

I chcę drwić usługi wstrzyknięte do 'myService' przed usługą zostanie wstrzyknięty do moich testów, więc mogę przetestować Kod inicjalizacji poniżej

var mySvc = { 
    params: {} 
    } 

    // Listen to route changes. 
    $rootScope.$on('$routeUpdate', mySvc.updateHandler); 

Używam Jasmine do testów i mocks. To właśnie wymyśliłem teraz:

describe('myService', function(){ 
    var rootScope, target; 
    beforeEach(function(){ 
    rootScope = jasmine.createSpyObj('rootScope', ['$on']); 

    module('myModule'); 
    angular.module('Mocks', []).service('$rootScope', rootScope); 
    inject(function(myService){ 
     target = myService; 
    });   
    }); 

    it('should be defined', function(){ 
    expect(target).toBeDefined(); 
    }); 

    it('should have an empty list of params', function(){ 
    expect(target.params).toEqual({}); 
    }); 

    it('should have called rootScope.$on', function(){ 
    expect(rootScope.$on).toHaveBeenCalled(); 
    }); 
}); 

To jednak nie działa. Mój makroskop korzeniowy nie zastępuje oryginału, a dokument Dependency Injection dezorientuje mnie bardziej niż cokolwiek innego.

Proszę o pomoc

Odpowiedz

7

bym szpiegował rzeczywistej $ rootScope zamiast próbować wstrzykiwać swój własny obiekt.

var target, rootScope; 
beforeEach(inject(function($rootScope) { 
    rootScope = $rootScope; 

    // Mock everything here 
    spyOn(rootScope, "$on") 
})); 

beforeEach(inject(function(myService) { 
    target = myService; 
})); 

it('should have called rootScope.$on', function(){ 
    expect(rootScope.$on).toHaveBeenCalled(); 
}); 

Przetestowałem to w CoffeScript, ale powyższy kod powinien nadal działać.

+0

Wielkie dzięki! Pracował jak urok. Nie mogę uwierzyć, że wcześniej tego nie próbowałem. –

+0

Musiałem dodać zmianę spyOn (rootScope, "$ on") do spyOn (rootScope, "$ on") .CallThrough(); ale działał świetnie i doprowadził mnie do właściwego kierunku. – blackmind

0

Można utworzyć RootController a następnie wstrzyknąć go:

inject(function(myService, $controller){ 
    target = myService; 
    $controller('rootController', { 
     $scope : $rootScope.$new(), 
     $rootScope : myService 
    }); 
}); 

Dzięki takiemu podejściu można uzyskać dostęp do funkcji $ rootScope z 'MyService'; Taki "myService. $ On()"

Po prostu to zrobiłem, daj mi znać, jeśli potrzebna jest pomoc.