当前位置: 首页 > 面试题库 >

使用Karma / Jasmine对modalInstance控制器进行单元测试

秦昊穹
2023-03-14
问题内容

编辑:本文末尾的“快速与肮脏”解决方案

我使用的是AngularUI-Bootstrap中的模式窗口,其方式与网站上说明的相同,只是我分割了文件。因此,我有:

CallingController.js:

$scope.delete = function () {
    if ($scope.selected.length > 0) {
        // [...]
        // preparing data
        // [...]
        var modalInstance = $modal.open({
            templateUrl: 'views/modalView.html',
            controller: 'modalCtrl',
            resolve: {
                itemArray: function () {
                    return $scope.selected;
                }
            }
        });
        modalInstance.result.then(function (confirm) {
            if (confirm === true) {
                // [...]
                // treat
                // [...]
            }
        });
    }
};

modalController.js:

myAppControllers.controller('modalCtrl',
    function ($scope, $modalInstance, itemArray) {

        $scope.accept = function () {
            $modalInstance.close(true);
        };

        $scope.reject = function () {
            $modalInstance.close(false);
        };

        $scope.itemArray = itemArray;

    });

当我使用Karma测试此代码(在karma配置文件中加载了 ui-bootstrap-tpls.min.js 文件)时,出现以下错误:
错误:[$ injector:unpr] [ http:// errors。
angularjs.org/1.2.15-build.2389+sha.c5f2f58/

$ injector / unpr?p0 =%24modalInstanceProvider%20%3C-%20%24modalInstance]
1错误(本机)
,表示茉莉花无法管理查找$
modalInstance的提供程序。

我什至没有在此控制器上测试东西,但这是我的茉莉花测试文件:

testModalController.js:

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

    beforeEach(module('myApp'));

    var Ctrl;
    var scope;

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

            Ctrl = $controller('modalCtrl', { $scope: scope });
        })
    );

    describe('Initial state', function () {
        it('should instantiate the controller properly', function () {
            expect(Ctrl).not.toBeUndefined();
        });

        it('should initialize its values properly', function () {

        });
    });

});

您对此问题有任何线索吗?它不是我使用(和测试)的第一个“外部”模块,并且我做了与其他模块相同的工作,只是这次不起作用,我也不知道为什么。

=========================================

编辑:快速且可能是肮脏的解决方案:

好的,因此基于Jasmine控制器实例化中的范围模拟方法,我弄清楚了如何“解决”我的问题,但是它可能很脏,因此,如果您找到一种更好的方式来实现我的意图,请随时发表评论。

testModalController.js:

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

    beforeEach(module('myApp'));

    var Ctrl;
    var scope;
    var modalInstance;

    // Initialize the controller and a mock scope
    beforeEach(inject(
        function ($controller, $rootScope, _$modal_) {
            scope = $rootScope.$new();
            modalInstance = _$modal_.open({
                templateUrl: 'views/modalView.html'
            });

            Ctrl = $controller('modalCtrl', {
                $scope: scope,
                $modalInstance: modalInstance,
                itemArray: function () { return ['a', 'b', 'c']; }
            });
        })
    );

    describe('Initial state', function () {
        it('should instantiate the controller properly', function () {
            expect(Ctrl).not.toBeUndefined();
        });

        it('should initialize its values properly', function () {

        });
    });

});

这样,Jasmine不再搜索提供程序,因为您已经注入了本来需要这些提供程序的项目。它有效,但是我相信可以用更好的方法来完成…


问题答案:

我通过创建模拟modalmodalInstance对象并验证它们已被我的控制器代码调用来解决此问题。由于modal并且modalInstance是第三方库的一部分,因此测试它们是否可以正常工作不是我们的责任-
而是测试调用该库的代码是否可以正常工作是我们的责任。

使用您的示例

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

  beforeEach(module('myApp'));

  var Ctrl;
  var scope;
  var modalInstance;

  // Initialize the controller and a mock scope
  beforeEach(inject(
    function ($controller, $rootScope) {     // Don't bother injecting a 'real' modal
      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')
        }
      };
      Ctrl = $controller('modalCtrl', {
        $scope: scope,
        $modalInstance: modalInstance,
        itemArray: function () { return ['a', 'b', 'c']; }
      });
    })
  );

  describe('Initial state', function () {
    it('should instantiate the controller properly', function () {
      expect(Ctrl).not.toBeUndefined();
    });

    it('should close the modal with result "true" when accepted', function () {
      scope.accept();
      expect(modalInstance.close).toHaveBeenCalledWith(true);
    });

    it('should close the modal with result "false" when rejected', function () {
      scope.reject();
      expect(modalInstance.close).toHaveBeenCalledWith(false);
    });
  });
});

这样,我们实际上就不需要对Angular-UI对象有任何依赖,并且我们的单元测试是很好且独立的。



 类似资料:
  • 问题内容: 对于我一生,我无法让$ httpBackend在执行$ http get请求的控制器上工作。我已经尝试了几个小时=) 我将其简化为下面可以最简单的形式。如果我通过测试 在控制器中注释掉$ http.get()请求 在测试中注释掉“ httpMock.flush()” 并更改“猪”和“狗”以匹配 也就是说,这是一个有效的工作测试和应用程序。 如果放回去,则会在底部显示错误。 app /

  • 本文向大家介绍使用Jasmine和Karma对AngularJS页面程序进行测试,包括了使用Jasmine和Karma对AngularJS页面程序进行测试的使用技巧和注意事项,需要的朋友参考一下 AngularJS是继jQuery之后发生在JavaScript上最好的东西。这也是JavaScript开发一直以来想要的方式。Angular主要的优点之一就是它的依赖注入(Dependency Inje

  • 问题内容: 我有一个与此类似的简单带注释的控制器: 我想用这样的单元测试来测试它: 问题是AnnotationMethodHandlerAdapter.handler()方法引发异常: 问题答案: 从Spring 3.2开始,有一种适当的方法可以轻松,优雅地进行测试。您将可以执行以下操作: 有关更多信息,请访问http://blog.springsource.org/2012/11/12/spri

  • 我对使用Spring控制器进行单元测试的概念是新的。我正在遵循我在网上找到的一些示例,并尝试实现他们的测试策略。这是我的基本控制器: 这是我的单元测试: 看起来很简单,但我得到了以下错误: 它完成了这项工作,但它没有像我之前尝试的那样使用任何Spring注释…这种方法是不好的,所以试图弄清楚为什么每当我在测试文件中包含注释时,总是会出现错误。 我的POM:

  • 我有一个请求表单的映射: 现在我想用MockMvcBuilders为此编写一个测试。不过,我不能这样做。 这里的挑战是请求处理程序需要使用Multipart/form-data,它由4个Multipart Files和1个Json数据组成。 有没有办法解决这个问题?请记住,我必须使用Spring 4.3。 如果您需要更多信息,请告诉我。

  • 问题内容: 我正在尝试创建一个简单的单元测试来测试我的表演功能。 我收到以下错误: 看来这不是控制器的范围吗? 这是我的控制器: 这是我的控制器单元测试: 问题答案: 为什么不简单地使用spyOn函数? 希望这可以帮助!