匿名回调函数中的 Jasmine spyOn 对象
Jasmine spyOn objects inside anonymous callback function
我需要对 controller
函数saveSettings()
进行单元测试,如下所示。我想测试 Session.setUrl()
是否被调用成功。我怎样才能做到这一点?
angular.module("test.controllers")
.controller('LoginCtrl', function($scope, Validator, Session, Notify){
$scope.apiUrl = "http://localhost:8080/web-server/";
$scope.saveSettings = function () {
Validator.validateUrl($scope.apiUrl,
function (url) { // success callback function
Session.setUrl(url);
},
function (error) { // failure callback function
Notify.alert('' + error);
}
);
};
});
服务定义如下:
angular.module('test.services')
.service('Validator', function () {
this.validateUrl = function(url, success, error) {
if ( !url ) {
error("URL not found!");
} else {
if (url.startsWith('http') && !url.startsWith('https')) {
url = url.replace('http', 'https');
}
success(url);
}
};
});
在下面的测试代码中(由@Etse 提供),Session.setUrl()
没有被调用:
describe('LoginCtrl', function(){
beforeEach(module('test.controllers');
beforeEach(inject($controller){
this.scope = {};
this.controller = $controller('LoginCtrl', {$scope: this.scope});
});
it('should call setUrl on success', inject(function(Session){
spyOn(Validator, 'validateUrl');
spyOn(Session, 'setUrl');
this.scope.saveSettings();
expect(Validator.validateUrl).toHaveBeenCalled();
expect(Session.setUrl).toHaveBeenCalled();
});
})
已解决 通过添加 callThrough()
如下:
spyOn(Validator, "validateUrl").and.callThrough();
我假设会话是一个服务,因为你正在使用依赖注入来获取它?应该可以只在服务上添加一个普通的间谍——只要你将它也注入到测试中。
在我的测试中,我只是设置了控制器,并在 this-conext 上公开了范围 - 这样我就可以在我的测试中访问它。
我在代码中发现了一些错误,并重写了它。
- 我发现了一些遗漏的括号
- $scope 未注入控制器
- 添加了模块依赖项
这是一个工作代码示例:
angular.module('test.services', [])
.service('Session', function(){
this.setUrl = function() {
console.log("test");
};
})
.service('Validator', function () {
this.validateUrl = function(url, success, error) {
if ( !url ) {
error("URL not found!");
} else {
if (url.startsWith('http') && !url.startsWith('https')) {
url = url.replace('http', 'https');
}
success(url);
}
};
});
angular.module("test.controllers", ['test.services'])
.controller('LoginCtrl', function($scope, Validator, Session){
$scope.apiUrl = "http://localhost:8080/web-server/";
$scope.saveSettings = function () {
Validator.validateUrl($scope.apiUrl,
function (url) { // success callback function
Session.setUrl(url);
},
function (error) { // failure callback function
console.log("notify");
}
);
};
});
//--- SPECS -------------------------
describe('LoginCtrl', function(){
beforeEach(function(){
module("test.controllers");
});
beforeEach(inject(function($controller){
this.scope = {};
this.controller = $controller('LoginCtrl', {$scope: this.scope});
}));
it('should call setUrl on success', inject(function(Session){
spyOn(Session, 'setUrl');
this.scope.saveSettings();
expect(Session.setUrl).toHaveBeenCalled();
}));
});
<script src="http://searls.github.io/jasmine-all/jasmine-all-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular-mocks.js"></script>
我需要对 controller
函数saveSettings()
进行单元测试,如下所示。我想测试 Session.setUrl()
是否被调用成功。我怎样才能做到这一点?
angular.module("test.controllers")
.controller('LoginCtrl', function($scope, Validator, Session, Notify){
$scope.apiUrl = "http://localhost:8080/web-server/";
$scope.saveSettings = function () {
Validator.validateUrl($scope.apiUrl,
function (url) { // success callback function
Session.setUrl(url);
},
function (error) { // failure callback function
Notify.alert('' + error);
}
);
};
});
服务定义如下:
angular.module('test.services')
.service('Validator', function () {
this.validateUrl = function(url, success, error) {
if ( !url ) {
error("URL not found!");
} else {
if (url.startsWith('http') && !url.startsWith('https')) {
url = url.replace('http', 'https');
}
success(url);
}
};
});
在下面的测试代码中(由@Etse 提供),Session.setUrl()
没有被调用:
describe('LoginCtrl', function(){
beforeEach(module('test.controllers');
beforeEach(inject($controller){
this.scope = {};
this.controller = $controller('LoginCtrl', {$scope: this.scope});
});
it('should call setUrl on success', inject(function(Session){
spyOn(Validator, 'validateUrl');
spyOn(Session, 'setUrl');
this.scope.saveSettings();
expect(Validator.validateUrl).toHaveBeenCalled();
expect(Session.setUrl).toHaveBeenCalled();
});
})
已解决 通过添加 callThrough()
如下:
spyOn(Validator, "validateUrl").and.callThrough();
我假设会话是一个服务,因为你正在使用依赖注入来获取它?应该可以只在服务上添加一个普通的间谍——只要你将它也注入到测试中。
在我的测试中,我只是设置了控制器,并在 this-conext 上公开了范围 - 这样我就可以在我的测试中访问它。
我在代码中发现了一些错误,并重写了它。
- 我发现了一些遗漏的括号
- $scope 未注入控制器
- 添加了模块依赖项
这是一个工作代码示例:
angular.module('test.services', [])
.service('Session', function(){
this.setUrl = function() {
console.log("test");
};
})
.service('Validator', function () {
this.validateUrl = function(url, success, error) {
if ( !url ) {
error("URL not found!");
} else {
if (url.startsWith('http') && !url.startsWith('https')) {
url = url.replace('http', 'https');
}
success(url);
}
};
});
angular.module("test.controllers", ['test.services'])
.controller('LoginCtrl', function($scope, Validator, Session){
$scope.apiUrl = "http://localhost:8080/web-server/";
$scope.saveSettings = function () {
Validator.validateUrl($scope.apiUrl,
function (url) { // success callback function
Session.setUrl(url);
},
function (error) { // failure callback function
console.log("notify");
}
);
};
});
//--- SPECS -------------------------
describe('LoginCtrl', function(){
beforeEach(function(){
module("test.controllers");
});
beforeEach(inject(function($controller){
this.scope = {};
this.controller = $controller('LoginCtrl', {$scope: this.scope});
}));
it('should call setUrl on success', inject(function(Session){
spyOn(Session, 'setUrl');
this.scope.saveSettings();
expect(Session.setUrl).toHaveBeenCalled();
}));
});
<script src="http://searls.github.io/jasmine-all/jasmine-all-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular-mocks.js"></script>