gpt4 book ai didi

unit-testing - 在 AngularJS 单元测试中模拟 $modal

转载 作者:行者123 更新时间:2023-12-03 05:32:31 27 4
gpt4 key购买 nike

我正在为 Controller 编写一个单元测试,该 Controller 会启动 $modal 并使用返回的 Promise 来执行某些逻辑。我可以测试触发 $modal 的父 Controller ,但我无法弄清楚如何模拟成功的 promise 。

我尝试了多种方法,包括使用 $q$scope.$apply() 来强制解决 Promise。然而,我得到的最接近的是将类似于 this 中最后一个答案的内容放在一起。所以帖子;

我已经在“旧”$dialog 模式中看到过几次这样的询问。我找不到太多关于如何使用"new"$dialog 模式执行此操作的信息。

一些指示将不胜感激。

为了说明问题,我使用 example provided in the UI Bootstrap docs ,进行了一些细微的修改。

Controller (主 Controller 和模态 Controller )

'use strict';

angular.module('angularUiModalApp')
.controller('MainCtrl', function($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];

$scope.open = function() {

$scope.modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function() {
return $scope.items;
}
}
});

$scope.modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
})
.controller('ModalInstanceCtrl', function($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};

$scope.ok = function() {
$modalInstance.close($scope.selected.item);
};

$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});

View (main.html)

<div ng-controller="MainCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I is a modal!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>

<button class="btn btn-default" ng-click="open()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>

测试

'use strict';

describe('Controller: MainCtrl', function() {

// load the controller's module
beforeEach(module('angularUiModalApp'));

var MainCtrl,
scope;

var fakeModal = {
open: function() {
return {
result: {
then: function(callback) {
callback("item1");
}
}
};
}
};

beforeEach(inject(function($modal) {
spyOn($modal, 'open').andReturn(fakeModal);
}));


// Initialize the controller and a mock scope
beforeEach(inject(function($controller, $rootScope, _$modal_) {
scope = $rootScope.$new();
MainCtrl = $controller('MainCtrl', {
$scope: scope,
$modal: _$modal_
});
}));

it('should show success when modal login returns success response', function() {
expect(scope.items).toEqual(['item1', 'item2', 'item3']);

// Mock out the modal closing, resolving with a selected item, say 1
scope.open(); // Open the modal
scope.modalInstance.close('item1');
expect(scope.selected).toEqual('item1');
// No dice (scope.selected) is not defined according to Jasmine.
});
});

最佳答案

当你在 beforeEach 中监视 $modal.open 函数时,

spyOn($modal, 'open').andReturn(fakeModal);

or

spyOn($modal, 'open').and.returnValue(fakeModal); //For Jasmine 2.0+

您需要返回 $modal.open 通常返回的模拟,而不是 $modal 的模拟,后者不包含 open功能如您在 fakeModal 中所述 mock 。假模态必须有 result包含 then 的对象存储回调的函数(单击“确定”或“取消”按钮时调用)。它还需要 close函数(模拟模式上的“确定”按钮单击)和 dismiss函数(模拟模式上的“取消”按钮单击)。 closedismiss函数在调用时会调用必要的回调函数。

更改 fakeModal执行以下操作,单元测试将通过:

var fakeModal = {
result: {
then: function(confirmCallback, cancelCallback) {
//Store the callbacks for later when the user clicks on the OK or Cancel button of the dialog
this.confirmCallBack = confirmCallback;
this.cancelCallback = cancelCallback;
}
},
close: function( item ) {
//The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
this.result.confirmCallBack( item );
},
dismiss: function( type ) {
//The user clicked cancel on the modal dialog, call the stored cancel callback
this.result.cancelCallback( type );
}
};

此外,您可以通过在取消处理程序中添加要测试的属性来测试取消对话框情况,在本例中 $scope.canceled :

$scope.modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$scope.canceled = true; //Mark the modal as canceled
$log.info('Modal dismissed at: ' + new Date());
});

设置取消标志后,单元测试将如下所示:

it("should cancel the dialog when dismiss is called, and $scope.canceled should be true", function () {
expect( scope.canceled ).toBeUndefined();

scope.open(); // Open the modal
scope.modalInstance.dismiss( "cancel" ); //Call dismiss (simulating clicking the cancel button on the modal)
expect( scope.canceled ).toBe( true );
});

关于unit-testing - 在 AngularJS 单元测试中模拟 $modal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21214868/

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