2013-06-12 16 views
6

Utworzyłem usługę Env, która zawiera informacje o środowisku i obecnie używam $location.host(), aby określić, w jakim środowisku się znajduję. Jak mam to udowodnić w moich testach?

Czytałem https://groups.google.com/forum/?fromgroups#!topic/angular/F0jFWC4G9hI, ale nie wydaje się do pracy, na przykład:

describe("Env (environment) service", function() { 

    var Env; 

    beforeEach(module('App')); 

    beforeEach(inject(
    ['Env', function(e) { 
     Env = e; 
    }] 
)); 

    describe("for staging", function() { 
    beforeEach(inject(function($location, $rootScope) { 
     $location.host("http://staging-site.com"); 
     $rootScope.$apply(); 
    })); 

    it("returns envrionment as staging", function() { 
     expect(Env.environment).toEqual("staging"); 
    }); 

    it("returns .isStaging() as true", function() { 
     expect(Env.isStaging()).toBeTruthy(); 
    }); 
    }); 
}); 

Próbowałem również wariant $browser, ale to nie działa. Jakieś pomysły?

+0

Próbowałem zostały również '$ browser.url()' zgodnie http://www.thecssninja.com/javascript/angular -location-testing, ale to też nie działa. – zlog

+0

Mam podobny problem, muszę wprowadzić $ location do mojego testu, ponieważ usługa tego wymaga. –

+1

https://github.com/angular/angular.js/issues/493 –

Odpowiedz

4

Miałem podobny problem i skorzystałem z usługi wtryskiwacza $. (Nie wiem, czy to najprostsze rozwiązanie, ale zadziałało to dla mnie :))

Ponieważ nie można polegać na lokalizacji w czasie testów, przygotowałem własną próbę. Najpierw musisz utworzyć metodę fabryczną. (Lub usługa lub dostawcą jeśli wolisz - patrz https://gist.github.com/Mithrandir0x/3639232 dla porównania):

function locationFactory(_host) { 
    return function() { 
    return { 
     /* If you need more then $location.host(), add more methods */ 
     host: function() { 
     return _host; 
     } 
    }; 
    }; 
} 

Następnie przed utworzeniem 'ENV', wtryskiwacz paszy z tym $ lokalizacji makiety:

module(function ($provide) { 
    $provide.factory('$location', locationFactory('http://staging-site.com')); 
}); 

Teraz każdy czas twój dostęp $ lokalizacja w twoim kodzie twój wstrzyknięcie jest wstrzykiwane, więc zwraca to, czego potrzebujesz. Więcej informacji na temat metody $ provide znajduje się pod numerem angular docs

Mam nadzieję, że pomoże to w przyszłości.

Aktualizacja: Widzę jedno miejsce, w którym mogłeś się pomylić (lub co najmniej byłoby błędne w moim rozwiązaniu). Wygląda na to, że uruchamiasz moduł "Env" (który jak sądzę natychmiast oblicza dane) i dopiero po tym zmienisz lokalizację $ - która może być już za późno.

6

Najlepszym sposobem jest użycie szpiedzy IMHO: http://tobyho.com/2011/12/15/jasmine-spy-cheatsheet/

// inject $location 
spyOn($location, "host").andReturn("super.domain.com"); 
var host = $location.host(); 
alert(host) // is "super.domain.com" 
expect($location.host).toHaveBeenCalled(); 
+1

Składnia dla jaśminu 2.0 i nowszego uległa zmianie, powinieneś użyć .and.returnValue() – wholladay

0

Oto kolejny sposób mock $ lokalizację, z Sinon.js

locationMock = { 
     path: sinon.spy() 
    }; 

i przykład twierdzenie:

locationMock.path.should.be.calledWith('/home'); 
2

Istnieje dobry przykład w dokumencie: https://docs.angularjs.org/guide/services

Przed rozpoczęciem tworzenia usługi chcesz się upewnić, że używasz $provide. Lubię używać $injector w testerze, aby najpierw określić lokalizację, a następnie utworzyć instancję usługi.

var mockLocation; 

    beforeEach(function() { 
    // control the $location.host() function 
    // which we fake in the testcases. 
    mockLocation = { 
     host: jasmine.createSpy() 
    }; 
    module(function($provide) { 
     $provide.value('$location', mockLocation); 
    }); 
    }); 

następnie

describe('staging server:', function() { 
    beforeEach(function() { 
     // mockLocation.host.andReturn('http://staging-site.com'); // jasmine 1.x 
     mockLocation.host.and.returnValue('http://staging-site.com'); 
    }); 

    it('returns envrionment as staging', inject(function($injector) { 
     Env = $injector.get('Env'); 
     expect(Env.environment).toEqual('staging'); 
    })); 
    }); 

i

describe('production server:', function() { 
    beforeEach(function() { 
     // mockLocation.host.andReturn('prod.example.com'); // jasmine 1.x 
     mockLocation.host.and.returnValue('prod.example.com'); 
    }); 

    it('returns envrionment as production', inject(function($injector) { 
     Env = $injector.get('Env'); 
     expect(Env.environment).toEqual('production'); 
    })); 
    });