【发布时间】:2014-05-29 12:24:48
【问题描述】:
在angularjs中,在测试服务时,我想检查返回的对象是否是Promise。
现在我正在做以下事情 -
obj.testMethod()
.should.be.instanceOf($q.defer());
【问题讨论】:
标签: angularjs unit-testing promise
在angularjs中,在测试服务时,我想检查返回的对象是否是Promise。
现在我正在做以下事情 -
obj.testMethod()
.should.be.instanceOf($q.defer());
【问题讨论】:
标签: angularjs unit-testing promise
您可以模拟 $http 并让它返回您创建的一些对象。然后您可以检查您的服务是否返回该对象。
【讨论】:
testMethod 返回一个 HttpPromise,带有成功和错误方法。我不想松开它们。
instanceOf 方法进行测试,那就太好了。你不这么认为吗?
查看源代码中的第 248 行 $q (https://github.com/angular/angular.js/blob/master/src/ng/q.js#L248) 并没有真正的检查可以确定。这将是你最好的选择
var deferred = method();
if(angular.isObject(deferred) &&
angular.isObject(deferred.promise) &&
deferred.promise.then instanceof Function &&
deferred.promise["catch"] instanceof Function &&
deferred.promise["finally"] instanceof Function){
//This is a simple Promise
}
如果promise实际上是一个可以使用new Promise()的函数,那么你可以使用promise instanceof Promise,但是它是一个对象,所以它没有任何特殊标识符,你唯一可以测试的就是它们特性。
编辑:
要测试“HttpPromise”,您可以添加在$http 服务(https://github.com/angular/angular.js/blob/master/src/ng/http.js#L726)中定义的error 和success 的检查:
var promise = $http(...);
if(angular.isObject(promise) &&
promise.then instanceof Function &&
promise["catch"] instanceof Function &&
promise["finally"] instanceof Function &&
promise.error instanceof Function &&
promise.success instanceof Function){
//This is a HttpPromise
}
额外:
如果您注意到 $http 实际上并没有返回 deferred,它会返回直接的承诺,如果您按照调用它实际上返回 $q.when(...) 并添加了几个函数。你可以看到$q.when 没有返回deferred,而是返回$q.deferred().promise,所以反过来$http(...) 永远不会是$q.deferred()
另外,如果您要运行您发布的测试,我希望您会收到此错误:
TypeError: Expecting a function in instanceof check, but got #<Object>
【讨论】:
HttpPromise 这不是真正的 $q 承诺。对吗?
$q.deffered(); 的新“实例”会丢失一些,尤其是成功和错误功能。这意味着它们不会“相等”,可以这么说,但它们仍然是承诺
测试一个对象是否是一个promise很简单:
return !!obj.then && typeof obj.then === 'function';
就是这样。如果一个对象有then 方法,它就是一个promise。
看起来 Angular 的 $q 与其他类型的 Promise 没有任何区别。
【讨论】:
.then 的任何内容视为承诺。
obj.then.length === 2 在第一次验证它是一个函数之后。 Promise 的 .then() 方法应该有两个形式参数(一个解析处理程序和一个拒绝处理程序),并且函数的 .length 属性应该返回该函数接受的形式参数的数量。
obj.then.length >= 2.
我正在处理回调,我需要点击事件的 CTA 来触发函数并确定触发的回调类型,这里有一些简单的示例。
let fn = function () { alert('A simple function') };
let cta = fn();
console.log(cta instanceof Promise);
// logs false
新的承诺示例
let fn = function () {
return new Promise(function (accept, reject) {
accept();
// reject();
});
};
let cta = fn();
if(cta instanceof Promise) {
cta.then(function () {
alert('I was a promise');
});
}
Axios 示例 1
let fn = function () {
return axios.get('/user');
}
let cta = fn();
if(cta instanceof Promise) {
cta.then(function () {
alert('I was a promise from axios');
});
}
// Triggers alert('I was a promise from axios');
Axios 示例 2
let fn = function () {
return axios.get('/user').then(response => {
console.log('user response', response.data);
});
}
let cta = fn();
if(cta instanceof Promise) {
cta.finally(function () {
alert('I was a final promise from axios');
});
}
// Triggers alert('I was a final promise from axios');
【讨论】: