2013-06-12 7 views
6

Я создал службу Env, которая обертывает информацию об окружающей среде, и в настоящее время я использую $location.host(), чтобы определить, в какой среде я нахожусь. Как я издеваться над этим в своих тестах?

Я прочитал https://groups.google.com/forum/?fromgroups#!topic/angular/F0jFWC4G9hI, но это не похоже на работу, например:

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(); 
    }); 
    }); 
}); 

Я также попробовал $browser вариант, но это не работает. Есть идеи?

+0

Я также попытался '$ browser.url()' в соответствии с http://www.thecssninja.com/javascript/angular -location-testing, но это тоже не работает. – zlog

+0

У меня есть аналогичная проблема, мне нужно ввести $ location в мой тест, поскольку это требует сервис. –

+1

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

ответ

4

У меня была аналогичная проблема, и я использовал услугу инжектора $. (Я не знаю, было ли это самое простое решение, но это сработало для меня :))

Так как $ location нельзя полагаться во время тестов, я подготовил свой собственный макет. Во-первых, вам нужно создать заводской метод. (Или услуг или поставщик, если вы предпочитаете - видеть https://gist.github.com/Mithrandir0x/3639232 для сравнения):

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

Тогда , прежде чем создать свой, кормить инжектор «окр» с этим $ местонахождения издеваться:

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

Теперь каждый время вашего доступа $ location в вашем коде, ваш макет вводится, поэтому он возвращает все, что вам нужно. Подробнее о способе предоставления $ angular docs

Надеюсь, это поможет вам в будущем.

Обновление: Я вижу одно место, когда вы, возможно, поступили не так (или, по крайней мере, было бы неправильно в моем решении). Похоже, вы инициируете модуль Env (который, я думаю, вычисляет данные немедленно), и только после этого вы меняете $ location - это может быть уже слишком поздно.

6

Лучший способ заключается в использовании шпионов ИМХО: 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

Синтаксис для жасмина 2.0 и выше изменился, вы должны использовать .and.returnValue() – wholladay

0

Вот еще один способ поиздеваться $ местоположение, с Sinon.js

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

и пример утверждения:

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

В документе есть хороший пример: https://docs.angularjs.org/guide/services

Вы должны убедиться, что используете $provide, прежде чем создавать экземпляр службы. Мне нравится использовать $injector в тестовой папке, чтобы сначала определить местоположение, а затем создать экземпляр службы.

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); 
    }); 
    }); 

затем

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'); 
    })); 
    }); 

и

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'); 
    })); 
    }); 
Смежные вопросы