如何解决AngularJS单元测试中的承诺

时间:2014-02-08 13:15:06

标签: javascript angularjs unit-testing jasmine promise

我正在使用基本的karma / jasmine设置来测试我的Angular代码。这是我的测试:

var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;

describe('main controller', function() {
   var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;


   beforeEach(inject(function($controller, $rootScope, $q) {
     scope = $rootScope.$new();
     $controllerConstructor = $controller;
     q = $q;
     mockSuperheroData = {
       getSuperheroes: function() {
         deferred = q.defer();
         return deferred.promise;
       }
     };
     ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
   }));

   it('should set the result of getResource to scope.heroes', function() {
     scope.getHeroes();
     expect(scope.heroes).toBe(100);
   });
}

scope.getHeroes()调用返回承诺的mockSuperheroData.getSuperheroes()。如何强制承诺在单元测试中返回我想要的内容?我在哪里可以勾勒出模仿其回报的承诺?

2 个答案:

答案 0 :(得分:4)

  

如何强制承诺在单元测试中返回我想要的内容?

基本上你需要拨打resolve on the Deferred

deferred.resolve(100);

您可以将其直接放在return deferred.promise之前,也可以放在异步setTimeout中。

答案 1 :(得分:2)

var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q;

describe('main controller', function() {
  var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q, rootScope;


  beforeEach(inject(function($controller, $rootScope, $q) {
    scope = $rootScope.$new();
    $controllerConstructor = $controller;
    q = $q;
    rootScope = $rootScope;
    mockSuperheroData = {
      getSuperheroes: function() {
        deferred = q.defer();
        return deferred.promise;
      }
    };
    ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}});
  }));

  it('should set the result of getResource to scope.heroes', function() {
    scope.getHeroes();

    deferred.resolve(100);
    rootScope.$apply();

    expect(scope.heroes).toBe(100);
  });
});

应该提到的是,因为$ q与$ rootScope集成,所以不仅需要解析延迟对象,还需要通过调用$ rootScope传播更改。$ apply。

我写了一篇关于在projectpoppycock

嘲笑角度承诺的博客

我在 plunkr

上写了一个带有测试的工作示例

我非常喜欢你通过使用$ controller服务注入模拟服务作为控制器依赖的方式,我可能需要修改我这样做的方式。你的方式更好:)谢谢!