【问题标题】:How to create unit-testing for $http promise in AngularJS如何在 AngularJS 中为 $http 承诺创建单元测试
【发布时间】:2015-07-27 06:43:34
【问题描述】:

我有一项服务,该服务具有使用 $http 承诺的功能。我想用茉莉花创建一个单元测试。

account.service('AccountService', ['$q', '$http', function ($q, $http) {
    this.getServerDataForUrl = function (url) {
         var def = $q.defer();
         $http.get(url)
              .success(function (data) {
                   if (data) {
                      def.resolve(data);
                   } else {
                      def.reject();
                   }
               })
               .error(function (error) {
                   if (data) {
                      def.resolve(data);
                   } else {
                      def.resolve();
                   }
                });
         return def.promise;
    };
}]);

更新:回调时更改一些代码。
我已经搜索过它,但它并没有给我这样的功能。任何人都给我一些例子来创建关于它的单元测试。我觉得这个功能很简单。谢谢。

【问题讨论】:

  • 这里唯一可以测试的是是否对特定的url进行了请求。网上测试http服务的例子很多。
  • 实际上您在代码中所做的事情是多余的。 $http 本身返回一个承诺。为什么需要这样的代码?
  • 嗨@Chandermani。这不是我的代码。我的任务是为它编写单元测试:)

标签: javascript angularjs unit-testing karma-jasmine


【解决方案1】:

你真的应该这样做

return $http.get(url);

将承诺包装在延迟对象中是没有意义的。

这是我能想到的唯一可测试的东西

describe('AccountService test', function() {
    var $http;

    beforeEach(module('accountModule', function($provide) {
        $provide.value('$http', $http = jasmine.createSpyObj('$http', ['get']));

        // if you aren't going to change the code to not wrap
        // the $http promise, add this

        var httpPromise = {
            success: function(cb) {
                cb('success');
                return httpPromise;
            },
            error: function(cb) {
                cb('error');
                return httpPromise;
            }
        };

        $http.get.and.returnValue(httpPromise);
    }));

    it('proxies through to $http.get', inject(AccountService) {
        AccountService.getServerDataForUrl('url');
        expect($http.get).toHaveBeenCalledWith('url');
    }));
});

【讨论】:

  • 我运行你的代码。但它得到消息:“TypeError:无法读取未定义的属性'成功'”。我现在可以用你的代码做什么?
  • @PhamMinhTan 我假设您会更新代码以不将 $http 承诺包装在延迟对象中。我已经更新了答案
  • 太棒了!您的代码运行正常。谢谢。你能给我一些教程和例子来编写单元测试吗?因为,我想写。反正。非常感谢。
【解决方案2】:

在规范中创建一个变量来保存您的 AccountService 实例的引用并使用角度注入函数将其实例化。

现在您可以使用 jasmine spys 来测试功能或使用 marchers 来测试服务公共成员。

    var AccountSvs = undefined;
    beforeEach(inject(function (AccountService) {
    AccountSvs = AccountService;
    }));

    it('..', function(){
      expect(AccountSvs.getServerDataForUrl).toBeDefined();
AccountSvs.getServerDataForUrl().then(/*success callback*/function(){}, /*error callback*/function(){}, /*notify callback*/function(){});
    });

【讨论】:

    【解决方案3】:

    在单元测试中处理 Promise 没什么大不了的,因为它是异步的,您需要执行以下操作。

    describe('AccountService',function(){
     var service = null;
        beforeEach(inject(function (AccountService) {
        service = AccountService;
        }));
    
        it('checkService here', function(done){
             expect(service .getServerDataForUrl).toBeDefined();
            service .getServerDataForUrl().then(function(resp){
             expect(resp.data).not.ToBeNull();   
              done();
    
         });
    });
    

    resp.data 将包含您从服务返回的实际数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-05
      • 2013-02-09
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多