可以/应该测试自定义的$ resource动作方法吗?

时间:2017-03-09 13:30:57

标签: angularjs unit-testing ecmascript-6 jasmine

在角度服务中,我有$资源操作方法,例如:

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方法的重点。我需要澄清这里的最佳做法。

1 个答案:

答案 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);

https://docs.angularjs.org/api/ngResource/service/$resource