【问题标题】:Unit testing promises in AngularJS with argumentsAngularJS 中带有参数的单元测试承诺
【发布时间】:2014-08-03 23:17:45
【问题描述】:

我们正在对我们的服务进行单元测试,并面临使用依赖服务参数监视方法的问题。

我正在为 ServiceA 编写单元测试

ServiceA.js

angular.module("App").service("ServiceA", function($http, ServiceB) {
    this.detail = null; 
    this.method = function(id){
        var sevrB = new ServiceB();
        return sevrB.getId(1).then(function(response) {
            this.detail = response.data;
        }); 
    };
 });

ServiceB.js(是工厂)

(function () {
    var dependencies = [
      '../module'
    ];
    define(dependencies, function (module) {
        return module.factory('ServiceB', function ($http) {
            var ServiceB= function () {
                this.id = null;               
            };

        ServiceB.prototype.getId = function(Id) {                               
            return $http.get('/test/');
        }
    }
 }());

单元测试代码

 describe('Testing ServiceA', function () {
 var serviceA, serviceBMock;

 beforeEach(function () {
     var _serviceBMock = function () {
         return {
             getId:function(id){
                 return 'test';
             }
         };
     };

     angular.module('ServiceAMocks', [])                   
         .value('ServiceB', _serviceBMock);
 });

beforeEach(module('ServiceAMocks'));       

beforeEach(inject(function (_ServiceA_, _ServiceB_) {
    serviceA=_ServiceA_;
    serviceBMock=_ServiceB_;
});

it('retrive Id', function () {  
   spyOn(serviceBMock,'getId').and.Return('test');
   serviceA.method(1);
});

}); 

我正在从 ServiceA 监视 ServiceB 的 getId 方法,如果我将 ServiceB 模拟为函数,我会收到以下错误

错误:getId() 方法不存在 在 jasmineInterface.spyOn

如果我将 serviceB 模拟为对象,那么我会得到错误

 TypeError: object is not a function

 var _serviceBMock = {              
     getId:function(id){
         return 'test';
     }
 }

而且我不确定在这种情况下测试承诺。

【问题讨论】:

  • 这是否正确:return ServiceB.getId(1)?建议回ServiceB.getId(id)
  • 我的 ServiceB 是一个工厂,充当对象模型,我在 Service A 中使用 new 运算符创建了这个工厂的实例。我已经编辑了上面的内容。
  • 只要不从工厂返回函数,就不需要用 new 调用工厂。
  • 谢谢,我已经在上面的内容中更新了我的 SevriceB 工厂的确切定义,并将其作为函数()返回。然后我使用 new 运算符将其转换为对象。如何进行单元测试对于这种情况??
  • 嗨,我可以通过在 beforeEach 块中使用 new as serviceBMock=new _ServiceB_(); 来解决这个问题的某些部分......但是现在我需要知道如何测试由返回的承诺serviceB.getId......

标签: angularjs unit-testing karma-runner jasmine2.0


【解决方案1】:

此版本支持 Jasmine 1.3

我正在注入 $q 服务,因为 ServiceB 想要调用方法。我们甚至可以继续解决返回的承诺,但这是测试的下一步。

回答以前版本的问题,AngularJS 注入 serviceB 的实例

describe('ServiceA', function () {
    var serviceA, ServiceB, $q;

    beforeEach(function () {
        module('App');
    });

    beforeEach(function () {
        module(function ($provide) {
            $provide.value('ServiceB', {
                getId: jasmine.createSpy('ServiceB.getId').andCallFake(function () {
                    return $q.all();
                })
            });
        });
    });

    beforeEach(inject(function (_ServiceA_, _ServiceB_, _$q_) {
        $q = _$q_;
        serviceA = _ServiceA_;
        ServiceB = _ServiceB_;
    }));

    describe('.method()', function () {
        it('returns ServiceB.getId() argument', function () {
            serviceA.method(1);
            expect(ServiceB.getId).toHaveBeenCalledWith(1);
        });
    });
});

jsfiddle:http://jsfiddle.net/krzysztof_safjanowski/sDh35/

【讨论】:

  • 您好,这个解决方案很好,但您错过了我的新操作员。我已经编辑了我上面的帖子并将 serviceB 创建为工厂,我将其用作对象模型并使用新操作员创建该工厂的实例和调用 serviceB 的方法。我的代码抛出 TypeError: object is not a function。
  • 如果 ServiceB 是作为函数返回的工厂并在 beforeEach 块中使用 new 运算符,则此方法不起作用。
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-05
  • 2020-03-12
相关资源
最近更新 更多