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

在Angular中进行单元测试指令控制器而无需使控制器成为全局控制器

郝冥夜
2023-03-14
问题内容

在Vojta
Jina的优秀存储库中,他在其中演示了指令的测试,他在模块包装器之外定义了指令控制器。看到这里:https : //github.com/vojtajina/ng-
directive-testing/blob/master/js/tabs.js

这不是不好的做法并且会污染全局名称空间吗?

如果在另一个地方可以合理地调用TabsController,那会不会很麻烦?

可以在此处找到针对上述指令的测试:https : //github.com/vojtajina/ng-directive-
testing/commit/test-controller

是否可以将指令控制器与指令的其余部分分开测试,而无需将控制器放在全局命名空间中?

将整个指令封装在app.directive(…)定义中会很好。


问题答案:

很好的问题!

因此,这是一个普遍的关注点,不仅对于控制器而言,而且对于指令可能需要执行其工作但不一定要将该控制器/服务暴露给“外部世界”的服务而言,都是潜在的问题。

我坚信 全局数据是有害的,应避免使用,这也适用于指令控制器
。如果采用这种假设,我们可以采用几种不同的方法来“本地”定义那些控制器。在这样做的时候,我们需要记住, 控制器应该仍然可以“轻松”地用于单元测试,
因此我们不能简单地将其隐藏在指令的闭包中。IMO的可能性是:

1)首先,我们可以简单地 在模块级别上定义指令的控制器 ,例如:

angular.module('ui.bootstrap.tabs', [])
  .controller('TabsController', ['$scope', '$element', function($scope, $element) {
    ...
  }])
 .directive('tabs', function() {
  return {
    restrict: 'EA',
    transclude: true,
    scope: {},
    controller: 'TabsController',
    templateUrl: 'template/tabs/tabs.html',
    replace: true
  };
})

这是我们基于Vojta的工作在https://github.com/angular-
ui/bootstrap/blob/master/src/tabs/tabs.js中使用的一种简单技术。

尽管这是一种非常简单的技术,但应注意,控制器仍然暴露于整个应用程序中,这意味着其他模块可能会覆盖它。从这个意义上讲,它使控制器对于AngularJS应用程序是本地的(因此不会污染全局窗口范围),但对于所有AngularJS模块也是全局的。

2) 使用闭包范围和特殊文件设置进行测试

如果要完全隐藏控制器功能,可以将代码包装在闭包中。这是AngularJS使用的技术。例如,查看NgModelController,我们可以看到它在自己的文件中被定义为“全局”函数(因此可以轻松地进行测试),但是整个文件在构建期间都被封装在闭包中:

  • https://github.com/angular/angular.js/blob/master/src/angular.prefix
  • https://github.com/angular/angular.js/blob/master/src/angular.suffix

综上所述:选项(2)比较“安全”,但是需要一些先期的构建步骤。



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

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

  • 问题内容: 我有以下情况: controller.js controllerSpec.js 错误: 我也尝试过类似的方法,但没有成功: 我该如何解决?有什么建议? 问题答案: 有两种方法(或肯定有更多方法)。 想象一下这种服务(无论它是工厂都没关系): 使用此控制器: 一种方法是使用要使用的方法创建对象并对其进行监视: 然后,将其作为dep传递给控制器​​。无需注入服务。那可行。 另一种方法是模拟

  • 本文向大家介绍AngularJS 单元测试控制器,包括了AngularJS 单元测试控制器的使用技巧和注意事项,需要的朋友参考一下 示例 控制器代码: 考试: 跑!

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

  • 问题内容: 编辑:本文末尾的“快速与肮脏”解决方案 我使用的是AngularUI-Bootstrap中的模式窗口,其方式与网站上说明的相同,只是我分割了文件。因此,我有: CallingController.js: modalController.js: 当我使用Karma测试此代码(在karma配置文件中加载了 ui-bootstrap-tpls.min.js 文件)时,出现以下错误: 错误:[