基于承诺单元测试code在角 [英] Unit-test promise-based code in Angular
问题描述
我有困难的时候试图测试基于承诺,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 calltasksService.removeAndGetNext
- when
tasksService.removeAndGetNext
is done it should change location (invokegoTo
)
在我看来,有单独测试这两个病例无捷径。
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屋!