![](/img/trans.png)
[英]How to test with Jasmine an AngularJS controller that calls service method that returns promise
[英]How to test Controller that calls a service where service uses $http
我正在尝试测试控制器。 控制器使用的服务使用$ http从json文件中获取数据(此json文件只是服务器返回的响应的模型)
我的问题是,当我测试控制器时,它会创建控制器对象,甚至调用服务。 但是它不会调用$ http模拟响应。 我不确定我要去哪里错。 我尝试查看一些示例,但所有示例均使用$ q。
我的服务如下所示:
(function(){
angular.module('mymodule')
.factory('MyService', MyService);
MyService.$inject = ['$http'];
function MyService($http) {
var service = {
retrieveData : retrieveData
};
return service;
function retrieveData(containerLabel){
var myGrossData = [];
var isMatchFound = false;
var myindex = containerLabel.slice(-4);
return $http.get('app/myGrossData.json').then(function(response) {
console.log('inside http retrieveData: ');
myGrossData = response.data;
var myindexExists = false;
var mydataObject = [];
var defaultdata = [];
angular.forEach(myGrossData, function (myGrossData) {
if (myindex === myGrossData.myindex) {
mydataObject = myGrossData;
isMatchFound = true;
}
if(!isMatchFound && myGrossData.myindex === '2006')
{
mydataObject = myGrossData;
}
if(myGrossData.myindex === '2006'){
defaultdata = myGrossData;
}
});
if (isMatchFound && response.status === 200)
{
return mydataObject;
}
else if(!isMatchFound && (response.status === 200 || response.status === 201)){
return defaultdata;
}
else //all other responses for success block
{
return 'Incorrect Response status: '+response.status;
}
},
function(error){
return 'Error Response: '+error.status;
}
);
}
};
})();
调用它的控制器是:
(function () {
'use strict';
angular
.module('mymodule', [])
.controller('MyCtrl', MyCtrl);
MyCtrl.$inject = ['$scope', 'MyService'];
function MyCtrl($scope, MyService) {
var vm = this;
vm.datafromsomewhere = datafromsomewhere;
vm.displayData = [];
vm.disableBarCode = false;
vm.childCount = 0;
vm.headertext="Master Container Builder";
init();
function init() {
console.log('MyCtrl has been initialized!');
console.log(vm.headertext);
}
function myfunctionCalledByUI(input) {
processData(input);
}
function processData(containerLabel){
MyService.retrieveMasterContainer(containerLabel).then(function(data){
vm.displayData = data;
});
vm.disableBarCode = true;
vm.childCount = (vm.displayData.childData === undefined) ? 0: vm.displayData.childData.length;
vm.headertext="Myindex "+vm.displayData.myindex;
if ( vm.displayData.masterDataId.match(/[a-z]/i)) {
// Validation passed
vm.displayData.masterDataId ="No Shipping Label Assigned";
}
else
console.log('else: '+vm.displayData.masterDataId);
console.log('length of childData: '+vm.childCount);
}
}
})();
最后我的规格看起来像这样:
var expect = chai.expect;
describe('Test Controller', function () {
var rootScope, compile; MyService = {};
var $scope, $controller;
beforeEach(module('ui.router'));
beforeEach(function() {
module('mymodule');
inject(function ($rootScope, _$compile_,_$controller_) {
rootScope = $rootScope;
compile = _$compile_;
$scope = $rootScope.$new();
MyService = jasmine.createSpyObj('MyService', [
'retrieveData'
]);
$controller = _$controller_('MyCtrl', {
$scope: $scope
});
});
});
it('controller should be initialized and data should also be initialized', function() {
expect($controller).to.not.be.undefined;
expect($controller).to.not.be.null;
expect($controller.disableBarCode).to.equal(false);
expect($controller.childCount).to.equal(0);
expect($controller.headertext).to.equal("Master Container Builder");
});
it(' should process data when containerLabel is called into myfunction', function() {
$controller.handKeyed('12001');
expect(MyService.retrieveData).to.have.been.called;
expect($controller.processData).to.have.been.called;
expect($controller.disableBarCode).to.equal(true);
expect($controller.childCount).to.equal(0);
expect($controller.headertext).to.equal("Master Container Builder");
});
});
如果有帮助,我正在使用以下techstack:
该代码在我运行时有效。 我的问题是,当我运行测试时,它不会填充vm.displayData变量中的数据。 我如何使它获取一些数据到服务中。 我添加了一些日志语句,它完全跳过了它。
在完成所有测试(包括与此测试无关的测试)之后,我将看到MyService的日志语句。 我不确定该如何处理。
我认为您正在寻找的是$httpBackend
服务。 它将模拟指示结果的请求。 因此,当您的服务访问该URL时,它将返回您传递给$httpBackend
配置的内容。
一个简单的例子是:
it('should list newest by category', function(){
$httpBackend
.expectGET(url)
.respond(techPosts /*YOUR MOCKED DATA*/);
$stateParams.category = 'tech';
var controller = $controller('HomeCtrl', { PostsResource: PostsResource, $stateParams: $stateParams });
controller.listNewestPosts();
$httpBackend.flush();
expect(controller.posts).toEqual(techPosts.posts);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.