gpt4 book ai didi

angularjs - 返回 promise 的单元测试服务 Angularjs Jasmine

转载 作者:行者123 更新时间:2023-12-02 19:12:50 24 4
gpt4 key购买 nike

根据 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
};

});

如果用户在对话框中单击“确定”,则调用删除方法时会执行 requestNotificationChannel.deleteMessage(id)

$scope.deleteMessage = function(id) {
var result = dialogFactory.confirmDeleteDialog();

result.then(function(response) {
requestNotificationChannel.deleteMessage(id);
});
};

问题是我无法对其进行单元测试。

这是我的测试。我已正确注入(inject) q 服务,但我不确定应该从 "confirmDeleteDialog" spy 返回什么...

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();
});
});

但我收到预期已调用 spy 删除消息。这意味着 result.then... 部分未执行。我缺少什么?

最佳答案

要模拟返回 Promise 的函数,它还需要返回 Promise,然后需要将其作为单独的步骤进行解析。

在您的情况下,您传递给 spy 的 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 中创建自己的延迟对象。您正在使用的(反)模式已被标记为“被遗忘的 promise ”,如 http://taoofcode.net/promise-anti-patterns/ 中所示。

当更简单,使用更少的代码,并且我认为可以更好地处理错误时,您可以只返回 $modal 服务创建的 promise :

var modalInstance = $modal.open({...});
return modalInstance.result;

如果您想修改调用函数所看到的内容,就已解决/拒绝的值而言,您可以通过返回 then 的结果来创建链式 Promise:

var modalInstance = $modal.open({...});
return modalInstance.result.then(function(successResult) {
return 'My other success result';
}, function(failureReason) {
return $q.reject('My other failure reason');
});

如果您不想将函数的内部工作原理暴露给调用者,您通常会想要这样做。这类似于同步编程中重新抛出异常的概念。

关于angularjs - 返回 promise 的单元测试服务 Angularjs Jasmine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22905581/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com