我试图在我的 Jasmine 测试中通过 $scope 检索 Controller ,但失败了。有人知道为什么吗?
当使用controllerAs语法时, Controller 对象使用controllerAs中指定的名称放置在$scope对象上。因此,通过使用 ng-app='MyApp' 在浏览器中运行下面的代码来引导到 Angular,我可以使用 chrome-dev 工具来定位并选择指令元素,然后输入 $0.scope().myDirCtrl
在控制台中。这确实产生了 Controller 对象,那么为什么我不能在单元测试中检索 Controller 对象呢?
运行下面的代码片段将启动独立的 jasmine 浏览器测试环境。测试的规范列在代码片段的底部。我遇到问题的代码是这样的:
expect($scope.myDirCtrl).toBeDefined();
/* --------------------------------------
Source code
--------------------------------------*/
(function(angular) {
'use strict';
// Setup the template -----------------
angular.module('MyApp.tpls', [])
.run(['$templateCache', function($templateCache) {
$templateCache.put('partials/myDirective.html',
'<div>{{myDirCtrl.testValue}}</div>');
}]);
// Setup the app ----------------------
angular.module('MyApp', ['MyApp.tpls'])
.directive('myDirective', myDirective)
.controller('MyDirectiveController', MyDirectiveController);
function myDirective() {
return {
restrict : 'E',
templateUrl : 'partials/myDirective.html',
transclude : true,
controllerAs : 'myDirCtrl',
bindToController: true,
scope : {},
controller : 'MyDirectiveController'
};
}
MyDirectiveController.$inject = ['$scope'];
function MyDirectiveController($scope) {
var ctrl = this;
ctrl.testValue = 'Only a test';
}
})(angular);
/* --------------------------------------
Test specifications
--------------------------------------*/
(function (module) {
'use strict';
// Define the tests -------------------
describe('My directive test', function () {
var $compile, $rootScope, $scope;
beforeEach(module('MyApp'));
beforeEach(inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
}));
it('scope should contain a controller reference', function () {
var element = $compile(angular.element('<my-directive></my-directive>'))($scope);
$scope.$digest();
expect($scope.myDirCtrl).toBeDefined();
});
});
})(module);
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/jasmine-html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.4/boot.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-mocks.js"></script>
最佳答案
问题是规范中的 $scope
与 MyDirectiveController
中使用的范围不同。指令为 Controller 创建了另一个作用域,该作用域成为规范作用域的子作用域。您应该能够在测试中借助 Angular 内部属性来检查它:
it('scope should contain a controller reference', function () {
var element = $compile(angular.element('<my-directive></my-directive>'))($scope);
$scope.$digest();
// controller is actually in a child scope
console.log($scope.$$childHead.myDirCtrl);
expect($scope.myDirCtrl).toBeDefined();
});
但我不建议依赖这些私有(private) Angular 属性,例如 $$childHead
,因为它们被认为是私有(private)的,不是公共(public) API 的一部分。我认为这个Q/A AngularJS - Access to child scope可以帮助您解决这个问题。
关于javascript - 在单元测试中通过 $scope 检索 Angular Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31072890/