Javascript 如何在angularjs测试中模拟$location.host()?

Javascript 如何在angularjs测试中模拟$location.host()?,javascript,testing,angularjs,mocking,Javascript,Testing,Angularjs,Mocking,我已经创建了一个封装环境信息的Env服务,目前我正在使用$location.host()确定我所处的环境。在我的测试中,我该如何嘲笑这一点 我读过,但似乎不起作用,例如: describe("Env (environment) service", function() { var Env; beforeEach(module('App')); beforeEach(inject( ['Env', function(e) { Env = e; }]

我已经创建了一个封装环境信息的
Env
服务,目前我正在使用
$location.host()
确定我所处的环境。在我的测试中,我该如何嘲笑这一点

我读过,但似乎不起作用,例如:

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
变体,但也不起作用。有什么想法吗?

我也有类似的问题,并且使用了$injector服务。(我不知道这是否是最简单的解决方案,但它对我有效:))

由于$location在测试期间不可靠,所以我准备了自己的mock。 首先,您需要创建一个工厂方法。(或服务或提供商,如果您愿意-请参阅以进行比较):

然后在创建“环境”之前,使用此$location mock馈送注射器:

module(function ($provide) {
  $provide.factory('$location', locationFactory('http://staging-site.com'));
});
现在,每次代码中的access$location被注入时,mock都会返回您需要的任何内容。 有关$PROFECT方法的更多信息,请参阅

希望这对你将来有所帮助


更新:我看到一个地方你可能出错了(或者至少在我的解决方案中是错的)。似乎您正在启动“Env”模块(我想它会立即计算数据),只有在这之后您才更改$location-这可能已经太晚了。

最好的方法是使用spies IMHO:


jasmine 2.0及更高版本的语法已更改如下

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

这里有另一种模拟$location的方法,使用Sinon.js

    locationMock = {
        path: sinon.spy()
    };
以及一个示例断言:

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

文档中有一个很好的例子:

在实例化服务之前,您需要确保使用
$provide
。我喜欢在testcase中使用
$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);
    });
  });
然后


我还尝试了根据的
$browser.url()
,但也不起作用。我有一个类似的问题,我需要在测试中插入$location,因为服务需要它。jasmine 2.0及更高版本的语法已更改,您应该使用.and.returnValue()
locationMock.path.should.be.calledWith('/home');
  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');
    }));
  });