在角度服务中,我有$资源操作方法,例如:
class FooService {
/*@ngInject*/
constructor($resource) {
this.Foo = $resource('/foo/:fooId/',
{fooId: '@fooId'},
{
bar: {
method: 'GET',
url: '/foo/:fooId/bar/',
isArray: true
}
);
}
getAllFoo() {
return this.Foo.query();
}
}
可以测试吗?
我已经对getAllFoo()这样的方法进行了测试,但我不太确定$ resource action方法。
可以直接在控制器中使用它们,如中
this.FooService.Foo.bar(params).$promise.then
?
他们应该接受测试吗? 如果是这样,怎么样?
编辑: 我知道如何测试getAllFoo():
describe('FooService', () => {
let $rootScope, $resource, $httpBackend, $log, $interval;
let makeFooService, translateMock;
let mockAllFoo = [
{"id": 123,"stuff": "asdf asdf"},
{"id": 124,"stuff": "hjghjg"}
];
beforeEach(window.module(FooModule.name));
beforeEach(inject((_$rootScope_, $q, _$resource_, _$httpBackend_, _$log_) => {
$rootScope = _$rootScope_;
queryDeferred = $q.defer();
$resource = _$resource_;
$httpBackend = _$httpBackend_;
$log = _$log_;
translateMock = { use: () => ({}) };
makeFooService = () => new FooService(_$resource_);
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('Service', () => {
it('has a resource-property [Foo]', () => {
let service = makeFooService();
expect(service.Foo).not.toBeNull();
});
it('should load all foos when getAllFoo() is called', () => {
$httpBackend.expect('GET', /(.+)\/foo/).respond( () => [200, mockAllFoo, 'success'] );
let service = makeFooService();
let allFoo = service.getAllFoo();
$httpBackend.flush();
expect(allFoo.length).toBe(2);
});
所以我知道如何测试getAllFoo()但不知道如何测试bar(); 如果bar是可测试的并且可以在控制器中直接使用,那么我没有看到像getAllFoo()这样的方法只是包装$ resource action方法的重点。我需要澄清这里的最佳做法。
答案 0 :(得分:1)
我认为这是一个好主意测试资源,一些资源可以有响应转换器或一些逻辑来创建URL请求。 Angular在http请求中为执行者测试提供了$ httpBackend,可以模拟http响应。
模拟请求
$httpBackend.when('GET', '/foo').respond({foo: 'bar'}, {'A-Token': 'xxx'});
发布HTTP响应
$httpBackend.flush();
https://docs.angularjs.org/api/ngMock/service/$httpBackend
是的,在我的选项中,只有在调用实际资源之前需要做一些逻辑时才需要创建“包装器”。
为了测试“bar”,您需要执行类似于以下代码的操作:
it('should call the correct url and handler the response right', (done)=>{
$httpBackend.expect('GET', '/foo/bar_id/bar/').respond( () => [200, {'id': 124,'stuff': 'hjghjg'}, 'success'] );
let service = makeFooService();
service.bar({fooId: 'bar_id'}).$promise.then(result =>{
expect(result).toEqual({'id': 124,'stuff': 'hjghjg'});
done();
});
$httpBackend.flush();
});
另外我认为可以直接从控制器调用资源方法。 $ resource提供了一个您不需要处理承诺的特定功能,您可以将响应值直接分配给var,如:
var bar = this.FooService.Foo.bar(params);