AngularJS测试 - 使用$ http和then()测试AngularUI的typeahead

时间:2013-11-27 14:59:49

标签: javascript angularjs twitter-bootstrap

我在使用typeahead.js(https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/typeahead.js)测试我的函数时遇到问题。我通常知道如何解决测试中的承诺,但不知道如下函数:

$scope.getSuggestion = function ( name, length ) {
  return $http.get( 'api/autocomplete/?contains=' + name )
    .then( function ( response ) {
      return response.data.slice( 0, length || 7 );
    });
};

我的测试看起来像这样:

describe('Suggestions', function () {
  it('should be possible to get suggestions', function () {
    $httpBackend.expectGET('api/autocomplete?title__contains=Foo').respond([
      { name: 'Foobar' },
      { name: 'Foobala' },
      { name: 'Foolooloo' }
    ]);
    var suggestions = $scope.getSuggestion( 'Foo' );
    $rootScope.$apply();

    // Here should be a test.
    console.log(suggestions);
  })
});

suggestion只是承诺对象Object{then: function (callback, errback) { ... }}

我在哪里搞砸了??

2 个答案:

答案 0 :(得分:2)

suggestions是一个承诺,是一个实际值,您需要调用then()来获取其中的值。那是

suggestions.then(function(data) {
    // Here should be a test.
    console.log(data);
});

更新

试试这个:

describe('Suggestions', function () {
  it('should be possible to get suggestions', function () {
    $httpBackend.expectGET('api/autocomplete?title__contains=Foo').respond([
      { name: 'Foobar' },
      { name: 'Foobala' },
      { name: 'Foolooloo' }
    ]);

    var suggestions;

    $scope.getSuggestion( 'Foo' ).then(function(data) {
        suggestions = data;
    });

    $httpBackend.flush();
    $rootScope.$apply(); // might be optional

    // Here should be a test.
    console.log(suggestions);
  })
});

答案 1 :(得分:0)

关于$httpBackend服务,为了“强制”它响应$http服务的请求,只需调用$httpBackEnd.flush();即可。我相信$rootScope.$apply();在这里是多余的。

关于$scope.getSuggestion方法的返回值,请注意它不会从服务器返回数据;它会返回一个promise对象,一旦满足对服务器的请求,它将被解析。

另请注意,promises可以链接,因此您的方法中$http(...).then(....)的结果仍然是一个承诺。

最后,在控制器thenreturn response.data.slice( 0, length || 7 );中作为参数传递的回调中的return语句将没有多大用处;当promise被解决并且调用了这个回调时,你将无法获得该返回值。

如果每次调用then方法时都需要执行某些操作,则可以在控制器方法内传递给getSuggestion的回调中提供代码。但是,如果该方法的“客户端”需要$http服务返回的数据,则必须注册自己的回调来检索它们。

因此,要在测试中实际获取响应数据(控制器方法的“客户端”),您需要在测试中注册相应的回调。

您可以使用promise“interface”的标准then方法,该方法希望您传递两个回调;如果请求成功,将调用第一个(在您的情况下,如果$ httpBackend被“训练”以响应2XX范围内的状态),第二个将在出现错误时被调用。或者,您可以使用AngularJS特定的successerror方法,因为$ http服务返回HttpPromise

您可以在此处查看此方法:http://jsfiddle.net/yianisn/rgk97/

另请参阅herehere