如何使用Jasmine测试AngularJS承诺返回的内容?

时间:2014-12-12 14:14:36

标签: javascript angularjs jasmine promise

我在工厂中有以下代码:

var app = angular.module('plunker', []);

app.factory('apiFactory', function($http) {
  return {
    'call':function(){
      $http.get('http://www.google.com').then(function(){
        return 'I visited Google!';
      });
    }
  };
});

以下的Jasmine测试:

describe('Testing apiFactory', function() {
  var $scope,
  apiFactory,
  $http,
  $q,
  rootScope;

  beforeEach(module('plunker'));

  beforeEach(inject(function($rootScope, _apiFactory_, _$http_, _$q_, _$rootScope_) {
    apiFactory = _apiFactory_;
    $http = _$http_;
    $q = _$q_;
    rootScope = _$rootScope_;
  }));

  it('should return "I visited Google!"', function(){
    var deferred = $q.defer();
    spyOn($http, 'get').and.returnValue(deferred.promise);
    deferred.resolve();
    apiFactory.call();
    rootScope.$apply();

    expect($http.get).toHaveBeenCalledWith('http://www.google.com');
  });
});

正如您在上面所看到的,我知道如何测试$ http.get承诺已被调用,但我如何测试传递给then()方法的函数返回"" I访问了Google!"?

以下是此代码的附加信息:http://plnkr.co/edit/DrKGV11eTpi2CrtYtffp

1 个答案:

答案 0 :(得分:1)

你几乎就在那里,你只需做几件事。

  1. 在apiFactory.call方法中,您应该返回$ http.get()。这将向呼叫者返回一个承诺。
  2. 您需要添加某种检查以验证结果是从apiFactory.call方法返回的。
  3. 我将您的测试修改为如下所示:

    it('should return "I visited Google!', function(){
      var deferred = $q.defer();
      var result;
    
      spyOn($http, 'get').and.returnValue(deferred.promise);
      deferred.resolve();
    
      apiFactory.call().then(function(resolved) {
        result = resolved;
      });
    
      expect($http.get).toHaveBeenCalledWith('http://www.google.com');
      expect(result).toBeUndefined();
    
      rootScope.$apply();
    
      expect(result).toBe('I visited Google!');
    });
    

    为了澄清,您的apiFactory.call方法应如下所示:

    return $http.get('http://www.google.com').then(function(){
      return 'I visited Google!';
    });
    

    这对你有用!