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

需要控制器的测试指令

仲鸿风
2023-03-14
问题内容

因此,我确实看到了另一个问题:如何在指令UT中模拟所需的指令控制器,这基本上是我的问题,但似乎该线程的答案是“更改设计”。我想确保没有办法做到这一点。我有一个指令声明一个由子指令使用的控制器。我现在正尝试为children指令编写茉莉花测试,但由于它们依赖于控制器,因此我无法让它们在测试中进行编译。看起来是这样的:

addressModule.directive('address', ['$http', function($http){
        return {
            replace: false,
            restrict: 'A',
            scope: {
                config: '='
            },
            template:   '<div id="addressContainer">' +
                            '<div ng-if="!showAddressSelectionPage" basic-address config="config"/>' +
                            '<div ng-if="showAddressSelectionPage" address-selector addresses="standardizedAddresses"/>' +
                        '</div>',
            controller: function($scope)
            {
                this.showAddressInput = function(){
                    $scope.showAddressSelectionPage = false;
                };

                this.showAddressSelection = function(){
                    $scope.getStandardizedAddresses();
                };

                this.finish = function(){
                    $scope.finishAddress();
                };
            },
            link: function(scope, element, attrs) {
              ...
            }
       }
}])

子指令:

addressModule.directive('basicAddress360', ['translationService', function(translationService){
        return {
            replace: true,
            restrict: 'A',
            scope: {
                config: '='
            },
            template:
                '...',
            require: "^address360",
            link: function(scope, element, attrs, addressController){
            ...
            }
       }
}])

茉莉花测试:

it("should do something", inject(function($compile, $rootScope){
            parentHtml = '<div address/>';
            subDirectiveHtml = '<div basic-address>';

            parentElement = $compile(parentHtml)(rootScope);
            parentScope = parentElement.scope();
            directiveElement = $compile(subDirectiveHtml)(parentScope);
            directiveScope = directiveElement.scope();
            $rootScope.$digest();
}));

我没有办法用茉莉花测试子指令吗?如果可以,我会缺少什么?即使我可以在没有控制器功能的情况下测试指令本身,我也会很高兴。


问题答案:

我可以想到两种方法:

1)同时使用两个指令

假设我们有以下指令:

app.directive('foo', function() {
  return {
    restrict: 'E',
    controller: function($scope) {
      this.add = function(x, y) {
        return x + y;
      }
    }
  };
});

app.directive('bar', function() {
  return {
    restrict: 'E',
    require: '^foo',
    link: function(scope, element, attrs, foo) {
      scope.callFoo = function(x, y) {
        scope.sum = foo.add(x, y);
      }
    }
  };
});

为了测试该callFoo方法,您可以简单地编译两个指令并bar使用use foo的实现:

it('ensures callFoo does whatever it is supposed to', function() {
  // Arrange
  var element = $compile('<foo><bar></bar></foo>')($scope);
  var barScope = element.find('bar').scope();

  // Act
  barScope.callFoo(1, 2);

  // Assert
  expect(barScope.sum).toBe(3);
});

工作柱塞。

2)模拟出foo的控制器

这不是很简单,也有些棘手。您可以element.controller()用来获取元素的控制器,并使用Jasmine对其进行模拟:

it('ensures callFoo does whatever it is supposed to', function() {
    // Arrange
    var element = $compile('<foo><bar></bar></foo>')($scope);
    var fooController = element.controller('foo');
    var barScope = element.find('bar').scope();
    spyOn(fooController, 'add').andReturn(3);

    // Act
    barScope.callFoo(1, 2);

    // Assert
    expect(barScope.sum).toBe(3);
    expect(fooController.add).toHaveBeenCalledWith(1, 2);
  });

工作柱塞。

当一个指令在其link功能中立即使用另一个控制器时,就会出现棘手的部分:

app.directive('bar', function() {
  return {
    restrict: 'E',
    require: '^foo',
    link: function(scope, element, attrs, foo) {
      scope.sum = foo.add(parseInt(attrs.x), parseInt(attrs.y));
    }
  };
});

在这种情况下,您需要分别编译每个指令,以便可以在第二个指令使用它之前对其进行模拟:

it('ensures callFoo does whatever it is supposed to', function() {
  // Arrange
  var fooElement = $compile('<foo></foo>')($scope);
  var fooController = fooElement.controller('foo');
  spyOn(fooController, 'add').andReturn(3);

  var barElement = angular.element('<bar x="1" y="2"></bar>')
  fooElement.append(barElement);

  // Act
  barElement = $compile(barElement)($scope);
  var barScope = barElement.scope();

  // Assert
  expect(barScope.sum).toBe(3);
  expect(fooController.add).toHaveBeenCalledWith(1, 2);
});

工作柱塞。

第一种方法比第二种方法容易得多,但是它依赖于第一个指令的实现,即您没有对单元进行测试。另一方面,尽管模拟指令的控制器不是那么容易,但是它可以让您更好地控制测试并消除对第一个指令的依赖。因此,明智地选择。:)

最后,我不知道执行上述所有操作的简便方法。如果有人知道更好的方法,请改善我的答案。



 类似资料:
  • 问题内容: 我可能会考虑将其完全倒退,但是我正在尝试制作三个嵌套指令,让它们称为:屏幕,组件和小部件。我希望窗口小部件能够触发组件中的某些行为,从而触发屏幕中的某些行为。所以: 我可以使用来在小部件的链接fn中要求父组件,但是如何进一步使组件控制器访问其包含的屏幕呢? 我需要的是WHAT in组件,因此,当您单击小部件的按钮时,它会发出“ screeny!”警报。 谢谢。 问题答案: 您可以通过以

  • 问题内容: 在Vojta Jina的优秀存储库中,他在其中演示了指令的测试,他在模块包装器之外定义了指令控制器。看到这里:https : //github.com/vojtajina/ng- directive-testing/blob/master/js/tabs.js 这不是不好的做法并且会污染全局名称空间吗? 如果在另一个地方可以合理地调用TabsController,那会不会很麻烦? 可以

  • 英文原文:http://emberjs.com/guides/testing/testing-controllers/ 单元测试方案和计算属性与之前单元测试基础中说明的相同,因为Ember.Controller集成自Ember.Object。 针对控制器的单元测试使用ember-qunit框架的moduleFor来做使这一切变得非常简单。 测试控制器操作 下面给出一个PostsController

  • spring-test模块对测试控制器@Controller提供了最原生的支持。详见14.6 "Spring MVC测试框架"一节。

  • 问题内容: 这里发生了什么? 这是我的指令: 这是使用中的指令的示例: 这是实际的错误文本: 问题答案: 如此处所述:Angular NgModelController ,您应提供所需的控制器

  • 在AWS控制台中创建ALB规则时,是否有入口控制器在后台运行? 当学习ALB入口控制器时,我有点困惑。我以为这只是对AWS中ALB服务的API调用。但是讲师似乎安装了一个aws入口控制器。然后编写规则来重定向到节点端口服务的路径。 与在AWS控制台中创建和通过kubernets集群进行创建相比,有什么不同。 这是正在安装的控制器。 https://github.com/kubernetes-sig