【问题标题】:Mocked function not found in AngularUI modal controller unit test在 AngularUI 模态控制器单元测试中找不到模拟函数
【发布时间】:2016-01-22 20:03:05
【问题描述】:

我正在使用Angular-Bootstrap modals 并且有一个像这样的基本控制器:

.controller('DashboardHelpController', ['$scope', '$uibModal', function ($scope, $uibModal) {

    var dhc = this;

    dhc.open = function (size, resource) {
        var modalInstance = $uibModal.open({
            templateUrl: 'resourcePlayModal.html',
            controller: 'ModalInstanceCtrl as mic',
            size: size,
            resolve: {
                resource: function () {
                    return resource;
                }
            }
        });
    };
}])

它调用一个标准的模态实例控制器:

.controller('ModalInstanceCtrl', ['$uibModalInstance', 'resource', function ($uibModalInstance, resource) {
    this.resource = resource;

    this.cancel = function () {
        $uibModalInstance.dismiss();
    };
}])

这是我的单元测试,以 another SO post 为模型:

describe('Modal controller', function () {
    var modalCtrl, scope, modalInstance;

    beforeEach(module('MyApp'));

    // initialize the controller and a mock scope
    beforeEach(inject(function ($controller, $rootScope) {
        scope = $rootScope.$new();

        modalInstance = {
            // create a mock object using spies
            close: jasmine.createSpy('modalInstance.close'),
            dismiss: jasmine.createSpy('modalInstance.dismiss'),
            result: {
                then: jasmine.createSpy('modalInstance.result.then')
            }
        };

        modalCtrl = $controller('DashboardHelpController', {
            $scope: scope,
            $uibModalInstance: modalInstance
        });
    }));

    it('should instantiate the mock controller', function () {
        expect(modalCtrl).not.toBeUndefined();
    });

    it('should have called the modal dismiss function', function () {
        scope.cancel;
        expect(modalInstance.dismiss).toHaveBeenCalled();
    });
});

问题是在作用域上找不到取消函数:

预期的间谍 modalInstance.dismiss 已用 [ 'cancel' 调用 ] 但它从未被调用过。

更新:我最初尝试将 cancel 作为函数调用:

it('should have called the modal dismiss function', function () {
    scope.cancel();
    expect(modalInstance.dismiss).toHaveBeenCalled();
});

那没用。我上面的代码是试图解决原来的问题:

TypeError: scope.cancel 不是函数

我对@9​​87654328@ 语法的使用有点复杂,但这应该可以。感谢您的帮助。

【问题讨论】:

  • 取消是一个函数。 scope.cancel 没有调用它。即使你有括号,cancel() 也是 ModalInstanceCtrl 的函数,你永远不会在任何地方实例化,而不是 $scope 的函数。
  • 没错。请看我的更新。 cancel() 是实例控制器的一个函数。我的问题在于我无法通过各种控制器和功能跟踪范围。
  • 不知道你为什么关心范围,因为 2 个控制器都没有使用它。为什么要在 DashboardHelpController 的测试中测试作为 ModalInstanceCtrl 的函数的 cancel()?
  • 范围是指被模拟的对象。不过,好问题。我在测试模态时的各种尝试可能让自己有点扭曲。您将如何测试模态的功能?我没有接受/拒绝类型的函数,只有一个视频播放模式。
  • 这里没有太多要测试的东西。您应该首先避免使用未定义的全局变量,例如resource。您唯一可以测试的是 dhc.open 使用预期的参数调用 $uibModal.open(),而 ModalInstanceCtrl.cancel() 调用 $uibModalInstance 上的 dismiss()。但是这样的单元测试并没有太大的价值。

标签: angularjs unit-testing jasmine angular-bootstrap


【解决方案1】:

scope.cancel 是一个函数,但您并没有这样调用它。

it('should have called the modal dismiss function', function () {
    scope.cancel();
    expect(modalInstance.dismiss).toHaveBeenCalledWith();
});

此外,scope.cancel() 从未在 DashboardHelpController 上定义,即使这是您为测试创建的范围。您需要在仪表板控制器上创建一个方法,该方法在创建 modalInstance 后调用模态实例 close 方法。

var modalInstance = $uibModal.open({
...
dhc.cancel = function ()  {
    modalInstance.dismiss();
}

【讨论】:

  • @CodeMed 我已经为您的问题添加了答案。
猜你喜欢
  • 2014-08-13
  • 1970-01-01
  • 2012-02-27
  • 2020-01-05
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
相关资源
最近更新 更多