zlo*_*log 6 javascript testing mocking angularjs
我创建了一个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();
});
});
});
Run Code Online (Sandbox Code Playgroud)
我也试过了这个$browser变种,但这也行不通.有任何想法吗?
最好的方法是使用间谍恕我直言: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();
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)
我遇到了类似的问题并使用了 $injector 服务。(我不知道这是否是最简单的解决方案,但它对我有用:))
由于在测试期间不能依赖 $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;
}
};
};
}
Run Code Online (Sandbox Code Playgroud)
然后在创建 'Env' 之前,使用此 $location 模拟提供注入器:
module(function ($provide) {
$provide.factory('$location', locationFactory('http://staging-site.com'));
});
Run Code Online (Sandbox Code Playgroud)
现在,每次您在代码中访问 $location 时,您的模拟都会被注入,因此它会返回您需要的任何内容。有关 $provide 方法的更多信息在Angular 文档中
希望这对您将来有所帮助。
更新:我看到一个地方你可能会出错(或者至少在我的解决方案中会出错)。看起来您正在启动“Env”模块(我猜它会立即计算数据),只有在此之后您才更改 $location - 这可能已经太晚了。