我正在尝试为angularcontroller编写一个karma单元测试,这是控制器。使用此处的文件上传(https://github.com/nervgh/angular-file-upload):
var c, di;
c = function($scope, FileUploader, UploadHelper, currentUser) {
var uploader;
$scope.uploader = uploader = new FileUploader(UploadHelper.getOptions());
uploader.onSuccessItem = function(item, response, status, headers) {
//do something
};
return this;
};
di = [ '$scope', 'FileUploader', 'UploadHelper', 'currentUser', c];
angular.module('mycontrollers').controller('DocumentsController', di);
我的茉莉花测试看起来像这样:
describe('Customer: Controller: DocumentsController', function() {
var $rootScope, DocumentMock, UserMock, documentsController, scope;
documentsController = $rootScope = scope = DocumentMock = UserMock = null;
beforeEach(function() {
module("mycontrollers");
return inject(function($controller, _$rootScope_, $q) {
var deferred, documents, fileUploader, uploadHelper, user;
$rootScope = _$rootScope_;
scope = $rootScope.$new();
documents = [
{
id: "doc 1",
documentType: "other"
}, {
id: "doc 2",
documentType: "pdf"
}, {
id: "doc 3",
v: "pdf"
}
];
user = {
id: 'user_id',
username: 'username'
};
UserMock = {
currentUser: function() {
return user;
}
};
fileUploader = {};
uploadHelper = {};
return documentsController = $controller('DocumentsController', {
documents: documents,
$scope: scope,
FileUploader: fileUploader,
UploadHelper: uploadHelper,
currentUser: UserMock
});
});
});
return describe("On creation", function() {
return it("should assign documents to scope", function() {
return expect(1).toEqual(1);
});
});
});
我有一个名为QuestionsAttachments的服务,它有一些依赖项:
s = function(API, $http, $q, $timeout) {
var QuestionsAttachments;
return QuestionsAttachments = (function() {
function QuestionsAttachments(data) {
angular.extend(this, data);
}
QuestionsAttachments["new"] = function(data) {
return new QuestionsAttachments(data);
};
return QuestionsAttachments;
})();
};
di = ['API', '$http', '$q', '$timeout', s];
这个问题是:如何模拟API,$ http,$ q,$ timeout?
这是一个关于plunkr的链接: http://plnkr.co/edit/BT8SJgW6ejcPw6xo1cpI?p=preview
答案 0 :(得分:0)
基本上你所做的就是设置间谍方法 服务。 你所要做的就是获得有害的服务(真正的实施) 并且只需要模拟/存根你需要的功能。无需创建自己的 像这样的模拟对象:
uploadHelper = {}
spyOn(uploadHelper, 'getOptions').andCallFake(function(){ // return data here }); // or you could use .Return({ /* some object */})
您可以阅读更多关于茉莉花和间谍的信息here
有了这个说我必须说提供的代码确实看起来有点不完整。
例如,通过提供的示例,您没有创建模块,而是直接使用getter语法而不是angular.module('mycontrollers', []);
。
其次在您的测试中,您试图在控制器实例化期间注入documents
,但由于您的控制器定义中没有可注入参数'documents',因此这将无法工作。
所以你遇到的问题可能是由于上面的概述。
无论如何,一个完整的例子,强调如何在UploadHelper.getOptions()上模拟/存根/间谍可能看起来像这样。这是一个有效的Plunkr http://plnkr.co/edit/RfQFsaLq8XV2FvMT3xr0?p=preview
angular
.module('mycontrollers',[])
.controller('DocumentsController', documentsController);
documentsController.$inject = ['$scope', 'FileUploader', 'UploadHelper', 'currentUser'];
function documentsController($scope, FileUploader, UploadHelper, currentUser){
var uploader;
$scope.uploader = uploader = new FileUploader(UploadHelper.getOptions());
uploader.onSuccessItem = function(item, response, status, headers){
// do something
};
}
describe('Customer: Controller: DocumentsController', function(){
beforeEach(function(){
module('mycontrollers');
inject(function($injector){
// fetch our dependencies
this.$controller = $injector.get('$controller');
this.FileUploader = $injector.get('FileUploader');
this.UploadHelper = $injector.get('UploadHelper');
this.$scope = $injector.get('$rootScope').$new();
this.user = {
id: 'user_id',
username: 'username'
};
this.UserMock = {
currentUser: function(){
return user;
}
}
});
});
function initController(context){
return context.$controller('DocumentsController', {
$scope: context.$scope,
FileUploader: context.FileUploader,
UploadHelper: context.UploadHelper,
currentUser: context.UserMock
});
}
describe('On creation', function(){
it('should call UploadHelper.getOptions()', function(){
// spy on getOptions and when it is getting called, return whatever we've specified
spyOn(this.UploadHelper, 'getOptions').andReturn({ /* some options */});
// instantiate the controller
initController(this);
expect(this.UploadHelper.getOptions).toHaveBeenCalled();
expect(this.$scope.uploader.onSuccessItem).toBeDefined();
});
});
});
答案 1 :(得分:0)
以下是为注入的服务创建完整模拟的简短示例。
var mockInjectedProvider;
beforeEach(function() {
module('myModule');
});
beforeEach(inject(function(_injected_) {
mockInjectedProvider = mock(_injected_);
});
beforeEach(inject(function(_base_) {
baseProvider = _base_;
}));
it("injectedProvider should be mocked", function() {
mockInjectedProvider.myFunc.andReturn('testvalue');
var resultFromMockedProvider = baseProvider.executeMyFuncFromInjected();
expect(resultFromMockedProvider).toEqual('testvalue');
});
//mock all service methods
function mock(angularServiceToMock) {
for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
spyOn(angularServiceToMock, Object.getOwnPropertyNames(angularServiceToMock)[i]);
}
return angularServiceToMock;
}