Jasmine:测试包含异步调用的void函数

时间:2015-02-06 09:56:21

标签: angularjs asynchronous jasmine

我想知道哪种方法可以测试不返回任何内容的函数(只是更改字段值)并包含异步调用。

这是我要测试的AngularJS控制器,我调用的服务返回一个promise(总是返回{name:“John”}):

app.controller('MyCtrl', function($scope, AsyncService) {

  $scope.greeting = "";
  $scope.error = 

  $scope.sayHello = function() {

    AsyncService.getName().then(
        function(data){
            $scope.saludo = "Hello " + data.name;
        },
        function(data){
              $scope.error = data;
        }
    );

  };

});

如果sayHello函数不包含异步调用,那么这将是规范,但它总是失败,因为scope.greeting总是为空。

describe('Test My Controller', function() {

  var scope, $httpBackend;

  // Load the module with MainController
  //mock Application to allow us to inject our own dependencies
  beforeEach(angular.mock.module('app'));

  //mock the controller for the same reason and include $rootScope and $controller
  beforeEach(angular.mock.inject(function($rootScope, $controller,_$httpBackend_){

      //Mock the service to always return "John" 
      $httpBackend = _$httpBackend_;
      $httpBackend.when('POST', 'http://localhost:8080/greeting').respond({name: "John"});

      //create an empty scope
      scope = $rootScope.$new();
      //declare the controller and inject our empty scope
      $controller('MyCtrl', {$scope: scope});
  }));

  it('$scope.greeting should get filled after sayHello', function() {
    expect(scope.greeting).toEqual("");
    scope.sayHello();
    expect(scope.greeting).toEqual("Hello John");
  });*/

});

我如何制作此规范来处理异步调用?我真的不明白如何以及在哪里使用Jasmine 2.0的“完成”标志。

1 个答案:

答案 0 :(得分:1)

使用$ q.defer()在模拟服务时从getName函数返回一个承诺。然后在创建控制器时将模拟传递给依赖项:

beforeEach(inject(function($controller, _$rootScope_, $q) {
    $rootScope = _$rootScope_;
    deferred = $q.defer();

    asyncService = {
        getName: function () {
        }
    };

    spyOn(asyncService, 'getName').and.returnValue(deferred.promise);

    $scope = $rootScope.$new(); 

    createController = function() {
        return $controller('MyCtrl', { $scope: $scope, AsyncService: asyncService } );
    };
}));

然后在致电$scope.hello()之后致电deferred.resolve(data)l,其中数据是您希望从承诺中的服务返回的数据。然后拨打$rootScope.$digest();

it('$scope.saludo should get filled after sayHello', function() {
    //Arrange
    var controller = createController();
    var data = {
      name: 'John'
    };

    //Act
    $scope.sayHello();
    deferred.resolve(data);
    $rootScope.$digest();

    //Assert
    expect($scope.saludo).toEqual('Hello ' + data.name);
});

Plunkr