基于承诺单元测试code在角 [英] Unit-test promise-based code in Angular

查看:187
本文介绍了基于承诺单元测试code在角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有困难的时候试图测试基于承诺,code在角。

I'm having hard times trying to test promise-based code in Angular.

我有以下的code在我的控制器:

I have the following code in my controller:

    $scope.markAsDone = function(taskId) {
        tasksService.removeAndGetNext(taskId).then(function(nextTask) {
            goTo(nextTask);
        })
    };

    function goTo(nextTask) {
        $location.path(...);
    }

我想单元测试以下情况:

I'd like to unit-test the following cases:


  • markAsDone 被称为它应该叫 tasksService.removeAndGetNext

  • tasksService.removeAndGetNext 做是应该改变的位置(调用 GOTO

  • when markAsDone is called it should call tasksService.removeAndGetNext
  • when tasksService.removeAndGetNext is done it should change location (invoke goTo)

在我看来,有单独测试这两个病例无捷径。

It seems to me that there is no easy way to test those two cases separately.

我所做的测试,第一次是:

What I did to test the first one was:

var noopPromise= {then: function() {}}
spyOn(tasksService, 'removeAndGetNext').andReturn(noopPromise);

现在来测试第二种情况下,我需要创建另一个虚假的承诺,这将是永远解析。这一切都相当乏味,这是一个很大的样板code的。

Now to test second case I need to create another fake promise that would be always resolved. It's all quite tedious and it's a lot of boilerplate code.

有没有其他的办法来测试这样的事情?还是我的设计味道?

Is there any other way to test such things? Or does my design smell?

推荐答案

您仍需要模拟的服务和回报的承诺,但你应该用真正的承诺来代替,这样你就不会需要实现其功能。使用 beforeEach 以创建已履行承诺,并嘲笑服务,如果你需要它总是被解决。

You will still need to mock the services and return a promise, but you should use real promises instead, so you don't need to implement its functionality. Use beforeEach to create the already fulfilled promise and mock the service if you need it to ALWAYS be resolved.

var $rootScope;

beforeEach(inject(function(_$rootScope_, $q) {
  $rootScope = _$rootScope_;

  var deferred = $q.defer();
  deferred.resolve('somevalue'); //  always resolved, you can do it from your spec

  // jasmine 2.0
  spyOn(tasksService, 'removeAndGetNext').and.returnValue(deferred.promise); 

  // jasmine 1.3
  //spyOn(tasksService, 'removeAndGetNext').andReturn(deferred.promise); 

}));

如果你宁愿preFER解决它在每个用不同的数据块,那么你只露出推迟到一个局部变量,并解决它在规范中。

If you'd rather prefer to resolve it in each it block with a different value, then you just expose the deferred to a local variable and resolve it in the spec.

当然,你会保持你的测试,因为他们,但是这里有一些非常简单的规范来告诉你它是如何工作的。

Of course, you would keep your tests as they are, but here is some really simple spec to show you how it would work.

it ('should test receive the fulfilled promise', function() {
  var result;

  tasksService.removeAndGetNext().then(function(returnFromPromise) {
    result = returnFromPromise;
  });

  $rootScope.$apply(); // promises are resolved/dispatched only on next $digest cycle
  expect(result).toBe('somevalue');
});

这篇关于基于承诺单元测试code在角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆