在Angular单元测试中模拟ngResource

时间:2016-10-05 14:48:34

标签: javascript angularjs jasmine karma-jasmine

我有ngResourceMockFactory,如下所示:

(function() {
  'use strict';

  angular.module('app')
    .factory('NgResourceMock', ngResourceMockFactory)
  ;

  ngResourceMockFactory.$inject = [];

  function ngResourceMockFactory() {
    function NgResourceMock() {
      var context = this;

      context.$promise.then = function() {
        context.prototype.$promise.then.apply(context, arguments);
      };

      context.$promise.finally = function() {
        context.prototype.$promise.finally.apply(context, arguments);
      };
    }

    NgResourceMock.prototype.$promise = {
      then: function(onSuccess, onError) {
        this.$promise.onSuccess = onSuccess;
        this.$promise.onError = onError;
      },
      finally: function(onComplete) {
        this.$promise.onComplete = onComplete;
      }
    };

    return NgResourceMock;
  }
})();

我将此注入我的beforeEach测试中,如此:

beforeEach(inject(function(NgResourceMock) {
  ngResourceMock = new NgResourceMock();
}));

然后我像这样使用它:

describe('initiateWorkflow function', function() {
  beforeEach(function() {
    vm.player = {id: 123};
    spyOn(dataService, 'initiateWorkflow').and.returnValue(ngResourceMock);
    vm.initiateWorkflow();
  });

  it('should call dataService.initiateWorkflow', function() {
    expect(dataService.initiateWorkflow).toHaveBeenCalledWith({playerId: vm.player.id}, {});
  });
});

但我一直看到以下错误:

TypeError: 'undefined' is not an object (evaluating 'context.prototype.$promise')

这让我相信我的ngResourceMockFactory出了问题,但我不确定它是什么。

2 个答案:

答案 0 :(得分:4)

不知道这是否有任何帮助,但如果您尝试评估测试中的异步操作,则可能需要在Jasmine中使用done()方法。

根据他们的文件:

beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
});

通过传递done作为beforeEach回调的参数,在每个之前的任何测试运行将等到调用done()函数。

来源:Jasmine(异步支持部分)。

希望这会有所帮助。

答案 1 :(得分:2)

以下是您问题的解决方案。

当您尝试在调用定义它的函数或定义父函数之前调用promise对象时,会导致错误TypeError: 'undefined' is not an object (evaluating 'context.prototype.$promise')

这里returnValue(ngResourceMock)直接调用函数而不需要定义上下文和参数。

因此,您可以尝试添加其他beforeEach语句,例如

beforeEach(angular.mock.module(app));

加载您的应用模块

这可能与您的问题 another link here.

相关

希望它可能对你有所帮助。