【问题标题】:Unknown Provider Error while trying to test generic angularjs $resource service尝试测试通用 angularjs $resource 服务时出现未知提供程序错误
【发布时间】:2015-05-05 02:19:55
【问题描述】:

我有为我的应用程序创建资源的通用服务:

(function(module) {
module.provider('restService', {

    resourceRegistry: {},
    addRestResource: function(entityName, entityProto) {
        this.resourceRegistry[entityName] = entityProto;
    },

    $get: function() {
        var restService;
        for (var entityName in this.resourceRegistry) {
            createRestResource(entityName, this.resourceRegistry[entityName]);
        };

        restService = {
            //createRestResource: createRestResource
        };

        return restService;
  }});

  function createRestResource(entityName, entityProto) {
    console.log('registering model: ' + entityName);
    module.provider(entityName, { $get: function($resource, $http) {
        var resource = $resource('/api/' + entityName + '/:id', { // TODO use config
            id : '@id' //this binds the ID of the model to the URL param
        },{
            query : { method : 'GET', isArray : true }, //this can also be called index or all
            update : { method : 'PUT' },
            create : { method : 'POST' },
            destroy : { method : 'DELETE' }
        });

        // here gose some other functionality unrelated to the topic...

        return resource;
    }});
}}(angular.module('restService', ['ngResource'])));

我可以被任何其他模块使用

module.config(['restServiceProvider', function(restServiceProvider) {
  restServiceProvider.addRestResource('User', { name: null, email: null });
}

虽然上面在应用程序中实际上对我有用实际上上面在应用程序中对我不起作用(由于重构之前留下了一些代码,它正在工作),我也无法工作 jasmine/karma测试它。问题是尝试各种方法来配置restServiceProvider 我总是以错误结束,例如TestEntity 有未知的提供者TestEntityProider。虽然我在创建资源之前尝试了不同的方法来配置resourceRegistry,但这里有一些测试文件。

describe('testing restService', function () {
    var httpBackend;
    var theRestServiceProvider;

    beforeEach(function() {
        module('ngResource');
        module('restService');
        var fakeModule = angular.module('test.app.config', ['ngResource'], function () {});
        fakeModule.config( function (restServiceProvider) {
            theRestServiceProvider = restServiceProvider;
            restServiceProvider.addRestResource('TestModel', {testProp: null});
        });

        module('test.app.config');
    });

    beforeEach(function () {
        inject(function ($httpBackend) {
            httpBackend = $httpBackend;
        })
    });

    beforeEach(inject(function (restService) {}));



    describe('create restService entity', function() {
        it('should post entity with nonempty testProp',
            function() {
                theRestServiceProvider.addRestResource('TestModel', {testProp: null});

                inject(function(TestModel) {
                    var object = new TestModel();
                    object.testProp = 'John Doe';

                    httpBackend.expectPOST(/.*/,
                        function(postData) {
                            console.log("post data: " + postData);
                            jsonData = JSON.parse(postData);
                            expect(jsonData.testProp).toBe(object.testProp);

                            return jsonData;
                        }).respond({});

                    var response = object.$create();

                    httpBackend.flush();
                });
            });
    });
});

IMO 这是因为在测试中注册资源“为时已晚”,但我仍然不知道如何正确执行此操作。

此处编辑是最终分辨率快捷方式

(function(module) {
  module.provider('restService', function($provide) {
    var provider = {};
    // all the provider stuff goes here

    function createRestResource(entityName, entityProto) {
      /* 
       * using $provider here is fundamental here to properly create 
       * 'entityName' + Provider in the runtime instead of module initialisation
       * block
       */
       $provide.factory(entityName, function($resource, $http) { /* ... */ };
       // do other stuff...
    }

    return provider;
  }
}(angular.module('restServiceModule', ['ngResource'])))

【问题讨论】:

    标签: angularjs testing jasmine angularjs-service angular-resource


    【解决方案1】:

    我在这里https://github.com/tunguski/matsuo-ng-resource/blob/master/matsuo-ng-resource.js做了非常相似的事情,也许对你有帮助。

    基本上,我将新的资源提供者添加到 $provide 而不是 module。有用。我认为这是主要区别。

    【讨论】:

    • 你是对的。使用 $provide 足以解决我的问题,因为它允许在运行时注册 $resource 提供程序。我将更正我的代码以显示确切的解决方案。希望它会对其他人有所帮助,因为即使修复如此简单,对我来说也不是那么容易弄清楚。
    【解决方案2】:

    我对业力/茉莉花不是很熟悉,但 BDD 语法似乎很相似。 据我了解,您应该有这样的东西

    beforeEach(function () {
        module('restService');
        inject(function (_$httpBackend_, _restService_, _ngResource_) {
            $httpBackend = _$httpBackend_;
            restService = _restService_;
            ngResource = _ngResource_;
        })
    });
    

    而不是你们所有人beforeEach。阅读更多here。 如果你想提供模拟而不是注入服务,你会使用

        module('restService', function($provide){
            $provide.value('serviceToMock', mockObject);
        });
    

    请注意,使用相同名称命名模块和提供者/服务/工厂可能会在后期混淆......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-24
      • 2015-07-16
      • 2017-03-22
      • 2015-10-11
      • 2017-08-10
      • 1970-01-01
      • 2016-11-08
      • 2011-05-11
      相关资源
      最近更新 更多