根据Michal Charemza帖子编辑。
我有一个代表angularui模态对话框的服务:
app.factory("dialogFactory", function($modal, $window, $q) {
function confirmDeleteDialog() {
var modalInstance = $modal.open({
templateUrl: "../application/factories/confirmDeleteDialog.htm",
controller: function($scope, $modalInstance) {
$scope.ok = function() {
$modalInstance.close("true");
};
$scope.cancel = function() {
$modalInstance.dismiss("false");
};
}
});
return modalInstance.result.then(function(response) {
return 'My other success result';
}, function(response) {
return $q.reject('My other failure reason');
});
};
return {
confirmDeleteDialog: confirmDeleteDialog
};
});
如果用户单击对话框中的“确定”,则在调用delete方法时将requestNotificationChannel.deleteMessage(id)
执行。
$scope.deleteMessage = function(id) {
var result = dialogFactory.confirmDeleteDialog();
result.then(function(response) {
requestNotificationChannel.deleteMessage(id);
});
};
问题是我无法对此进行单元测试。
这是我的考验。我已经正确注入了q服务,但是我不确定应该从"confirmDeleteDialog"
间谍那里返回什么…
describe("has a delete method that should call delete message notification", function() {
var deferred = $q.defer();
spyOn(dialogFactory, "confirmDeleteDialog").and.returnValue(deferred.promise);
spyOn(requestNotificationChannel, "deleteMessage");
$scope.deleteMessage(5);
deferred.resolve();
it("delete message notification is called", function() {
expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
});
});
但是我正在接受expected spy deleteMessage to have been called
。这意味着result.then
…部分没有执行。我想念什么?
要模拟返回承诺的函数,它还需要返回承诺,然后需要将其作为单独的步骤进行解析。
在您的情况下,deferred.resolve()
您传递给间谍的内容需要替换为deferred.promise
,并且deferred.resolve()分别执行。
beforeEach(function() {
var deferred = $q.defer();
spyOn(dialogFactory, "confirmDeleteDialog").and.returnValue(deferred.promise);
spyOn(requestNotificationChannel, "deleteMessage");
$scope.deleteMessage(5);
deferred.resolve();
$rootScope.$digest();
});
it("delete message notification is called", function() {
expect(requestNotificationChannel.deleteMessage).toHaveBeenCalled();
});
我怀疑您还需要调用$rootScope.$digest()
,因为Angular的promise实现与摘要循环相关。
另外,与您的问题略有关系,但我认为您无需在中创建自己的延迟对象confirmDeleteDialog
。您正在使用的(反)模式已标记为“被遗忘的承诺”,如http://taoofcode.net/promise-
anti-patterns/
当更简单,使用更少的代码并且我认为可以更好地处理错误时,您可以返回$modal
服务创建的承诺:
var modalInstance = $modal.open({...});
return modalInstance.result;
如果要修改调用函数所看到的内容(根据已解析/拒绝的值),可以通过返回以下结果来创建链式承诺then
:
var modalInstance = $modal.open({...});
return modalInstance.result.then(function(successResult) {
return 'My other success result';
}, function(failureReason) {
return $q.reject('My other failure reason');
});
如果您不想向调用者公开函数的内部功能,通常会希望这样做。这类似于在同步编程中重新引发异常的概念。
问题内容: 我有使用,它可以进行远程调用,并返回promise: 要对我进行单元测试,需要模拟,以便其方法返回promise。这是我的方法: 从上面可以看到,我的模拟的定义取决于,我必须使用来加载。此外,应该在中进行注入模拟,这应该在之前进行。但是,更改模拟后,其值不会更新。 正确的方法是什么? 问题答案: 我不确定为什么您的方法不起作用,但是我通常使用该函数来完成。像这样: 还要记住,您将需要调
问题内容: 关于这两个重要来源:NZakas- 承诺链中的归还承诺 和MDN承诺,我想提出以下问题: 每次我们从承诺履行处理程序返回值时,该值如何传递给从同一处理程序返回的新承诺? 例如, 在这个例子中,是一个承诺。也是来自履行处理程序的承诺。但是。取而代之的是神奇地解决(如何?),然后将该值传递给的实现处理程序。即使是这里的句子也令人困惑。 您能给我解释一下这到底是怎么回事吗?我对这个概念感到困
问题内容: 在Angular中,所有内容似乎都具有陡峭的学习曲线,并且对Angular应用程序进行单元测试绝对不能逃脱这种范例。 当我开始使用TDD和Angular时,我觉得我花了两倍(可能更多)的时间来弄清楚如何测试,甚至花更多的时间来正确地设置测试。但是正如Ben Nadel 在他的博客中所说的那样,角度学习过程存在起伏。他的图表绝对是我在Angular的经历。 但是,随着我在学习Angula
问题内容: 我有使用,它可以进行远程调用,并返回promise: 要对我进行单元测试,需要模拟,以便其方法返回promise。这是我的方法: 从上面可以看到,我的模拟的定义取决于,我必须使用进行加载。此外,应该在中进行注入模拟,这应该在之前进行。但是,更改模拟后,其值不会更新。 正确的方法是什么? 问题答案: 我不确定为什么您的方法行不通,但是我通常使用该函数来完成。像这样: 还要记住,您将需要调
问题内容: 我正在使用茉莉花对angularjs控制器进行单元测试,该控制器在范围内将变量设置为调用返回promise对象的服务方法的结果: 服务内部: 在我的angularjs应用程序上下文中,这可以正常工作,但在茉莉花单元测试中则无法工作。我已经确认“ then”回调在单元测试中正在执行,但是$ scope.myVar承诺永远不会设置为回调的返回值。 我的单元测试: 另外,如果我将控制器更改为
我试图实现一个单元测试的在与。 我在关注这个链接,它运行良好,但结果为空,当我用浏览器测试我的websocket时,它会发送所需的结果。 让我展示一下我的测试课 } 这是我的< code > WebSocketConfiguration 类 } 这是我从服务器得到的响应 更新: 在下面的答案中添加建议的更改并经过进一步的研究后,我的测试类现在看起来像这样 } 经过这些更改后,我现在可以将堆栈跟踪打