Angularjs 如何测试工厂?
我在角度服务中使用$resource。 我希望使用基于$cacheFactory的自定义缓存,而不是内置的$http缓存,以便在REST服务返回响应时操作缓存 我在单元测试中模拟$cacheFactory时遇到了很大的困难,有人能帮我为我的测试定义正确的模拟和设置吗 下面是我试图测试的代码的简化版本。请注意,我正在告诉我的angular应用程序在myApp.run中使用自定义缓存“DefaultCache”,而不是默认的$http缓存。我理解这是替换所有$resource服务的默认缓存的方法 代码 测试 这是我的测试设置。注意:提供的mockCacheFactory返回一个对象:Angularjs 如何测试工厂?,angularjs,unit-testing,caching,Angularjs,Unit Testing,Caching,我在角度服务中使用$resource。 我希望使用基于$cacheFactory的自定义缓存,而不是内置的$http缓存,以便在REST服务返回响应时操作缓存 我在单元测试中模拟$cacheFactory时遇到了很大的困难,有人能帮我为我的测试定义正确的模拟和设置吗 下面是我试图测试的代码的简化版本。请注意,我正在告诉我的angular应用程序在myApp.run中使用自定义缓存“DefaultCache”,而不是默认的$http缓存。我理解这是替换所有$resource服务的默认缓存的方法 代
///<reference path="~/Scripts/jasminejs/jasmine.js"/>
///<reference path="../../Web/Scripts/angularjs/angular.js"/>
///<reference path="../../Web/Scripts/angularjs/angular-mocks.js"/>
///<reference path="../../Web/Scripts/angularjs/angular-resource.js"/>
describe("MyServiceSpec", function () {
beforeEach(module('myServices'));
describe('GivenThingsResource', function () {
var $httpBackend, MyService, mockCacheFactory;
beforeEach(module(function ($provide) {
mockCacheFactory = {
get: function (cacheName) {
return {
get: function (key) { },
put: function (key, value) { },
};
},
};
$provide.value('$cacheFactory', mockCacheFactory);
}));
beforeEach(inject(function (_$httpBackend_, _MyService_) {
$httpBackend = _$httpBackend_;
MyService = _MyService_;
spyOn(mockCacheFactory, 'get').andCallThrough();
}));
it("WhenQuery_ThenReturnsData", function () {
$httpBackend.expectGET('/api/things').respond(JSON.stringify({ Things: [{ Id: '1' }, { Id: '2' }] }));
var result = MyService.things.query();
$httpBackend.flush();
expect(result).toEqualData({ Things: [{ Id: '1' }, { Id: '2' }] });
});
});
});
因此,我认为我的mock是错误的,因此我将提供的mockCacheFactory更改为函数,以便调用$cacheFactory'$http'应该成功:
mockCacheFactory = function () {
return {
get: function (cacheName) {
return {
get: function (key) { },
put: function (key, value) { },
};
},
};
};
但我现在得到了这些错误:
TypeError: 'undefined' is not a function (evaluating '$cacheFactory.get('defaultCache')')
TypeError: 'undefined' is not a function (evaluating '$cacheFactory.get('defaultCache')')
at TestSpec.js: line 25
at invoke ( angular.js: line 3966)
at angular.js: line 3808
at getService ( angular.js: line 3930)
at invoke ( angular.js: line 3957)
at workFn ( angular-mocks.js: line 2161)
at jasmine.js: line 1064
at jasmine.js: line 2096
at jasmine.js: line 2086
undefinedTypeError: 'undefined' is not an object (evaluating '$httpBackend.expectGET') in http://localhost:40529/Tests.js (line 78)
TypeError: 'undefined' is not an object (evaluating '$httpBackend.expectGET')
at TestSpec.js: line 78
at jasmine.js: line 1064
at jasmine.js: line 2096
at jasmine.js: line 2086
请帮忙
我真的不明白在我的mock中需要什么来满足使用我的mock的代码。它似乎需要一些javascript二元性,我不知道如何在我的mock定义中进行模仿
有人知道我的模拟应该如何构建吗?或者我在这里还遗漏了什么?对于以后遇到同样问题的人 我找不到任何方法来构建适用于此代码的mock。我甚至从github获得了$cacheFactory的实现,剥离了它的实现,并尝试使用它作为模拟,将其插入测试。那里也没有运气 然而,我确实遇到了一篇随机的帖子,暗示也许我应该在我自己的服务中创建一个cachingservice,它将使用$cacheFactory创建一个缓存。然后,我就可以将我的cachingservice注入到我的资源中,而不是直接使用$cacheFactory。模拟缓存服务应该很简单 我做到了,现在没事了 我的新缓存服务:
myServices.factory('ServiceCachingService', [
'$cacheFactory',
function (
$cacheFactory
) {
return $cacheFactory('defaultCache');
}]);
新建app.run:
myApp.run([
'$http',
'ServiceCachingService',
function ($http, ServiceCachingService) {
// Replace default $http cache with one we can control
$http.defaults.cache = ServiceCachingService;
}]);
我的新数据服务:
myServices.factory('MyService', [
'$resource',
'ServiceCachingService',
function($resource, ServiceCachingService) {
function doSomething(data) {
var cached = ServiceCachingService.get('akey');
return angular.fromJson(data);
}
return {
things: $resource('/api/things/:id', { id: '@id' }, {
query: {
method: 'GET',
isArray: true,
cache: true,
transformResponse: function(data) {
return doSomething(data);
},
},
})
}
}]);
然后是新的模拟测试:
mockCachingService = {
get: function (key) {},
put: function (key, value) { },
};
对于任何一个后来有同样问题的人 我找不到任何方法来构建适用于此代码的mock。我甚至从github获得了$cacheFactory的实现,剥离了它的实现,并尝试使用它作为模拟,将其插入测试。那里也没有运气 然而,我确实遇到了一篇随机的帖子,暗示也许我应该在我自己的服务中创建一个cachingservice,它将使用$cacheFactory创建一个缓存。然后,我就可以将我的cachingservice注入到我的资源中,而不是直接使用$cacheFactory。模拟缓存服务应该很简单 我做到了,现在没事了 我的新缓存服务:
myServices.factory('ServiceCachingService', [
'$cacheFactory',
function (
$cacheFactory
) {
return $cacheFactory('defaultCache');
}]);
新建app.run:
myApp.run([
'$http',
'ServiceCachingService',
function ($http, ServiceCachingService) {
// Replace default $http cache with one we can control
$http.defaults.cache = ServiceCachingService;
}]);
我的新数据服务:
myServices.factory('MyService', [
'$resource',
'ServiceCachingService',
function($resource, ServiceCachingService) {
function doSomething(data) {
var cached = ServiceCachingService.get('akey');
return angular.fromJson(data);
}
return {
things: $resource('/api/things/:id', { id: '@id' }, {
query: {
method: 'GET',
isArray: true,
cache: true,
transformResponse: function(data) {
return doSomething(data);
},
},
})
}
}]);
然后是新的模拟测试:
mockCachingService = {
get: function (key) {},
put: function (key, value) { },
};
下面的代码将允许您在单元测试中模拟$cacheFactory。$provide服务将允许服务依赖项注入使用$cacheFactory而不是默认的$cacheFactory
var cache, $cacheFactory; //used in your its
beforeEach(function(){
module(function ($provide) {
$cacheFactory = function(){};
$cacheFactory.get = function(){};
cache = {
removeAll: function (){}
//add other methods here
};
spyOn(cache, 'removeAll');
spyOn($cacheFactory, 'get').and.returnValue(cache);
$provide.value('$cacheFactory', $cacheFactory);
});
});
describe('yourFunction', function(){
it('calls cache.remove()', function(){
yourService.yourFunction();
expect(cache.remove).toHaveBeenCalled();
});
});
下面的代码将允许您在单元测试中模拟$cacheFactory。$provide服务将允许服务依赖项注入使用$cacheFactory而不是默认的$cacheFactory
var cache, $cacheFactory; //used in your its
beforeEach(function(){
module(function ($provide) {
$cacheFactory = function(){};
$cacheFactory.get = function(){};
cache = {
removeAll: function (){}
//add other methods here
};
spyOn(cache, 'removeAll');
spyOn($cacheFactory, 'get').and.returnValue(cache);
$provide.value('$cacheFactory', $cacheFactory);
});
});
describe('yourFunction', function(){
it('calls cache.remove()', function(){
yourService.yourFunction();
expect(cache.remove).toHaveBeenCalled();
});
});
今天,我在同一个问题上苦苦挣扎,找到了一个不同的解决方案。角度1.3.13 显然$cacheFactory有一个get方法,因此您可以检索cacheId的实例。 这将使您能够监视正确的缓存实例
beforeEach(inject(function (_$cacheFactory_) {
mockCache = _$cacheFactory_.get('defaultCache');
}));
今天,我在同一个问题上苦苦挣扎,找到了一个不同的解决方案。角度1.3.13 显然$cacheFactory有一个get方法,因此您可以检索cacheId的实例。 这将使您能够监视正确的缓存实例
beforeEach(inject(function (_$cacheFactory_) {
mockCache = _$cacheFactory_.get('defaultCache');
}));