Angularjs 使用templateUrl时,isolateScope()返回undefined

Angularjs 使用templateUrl时,isolateScope()返回undefined,angularjs,unit-testing,angularjs-directive,karma-runner,Angularjs,Unit Testing,Angularjs Directive,Karma Runner,我有一个我想进行单元测试的指令,但是我遇到了一个问题,我无法访问我的隔离作用域。以下是指令: <my-directive></my-directive> 下面是我的单元测试: describe('Directive: myDirective', function() { var $compile, $scope, $log; beforeEach(function() { // Load template using a Karma p

我有一个我想进行单元测试的指令,但是我遇到了一个问题,我无法访问我的隔离作用域。以下是指令:

<my-directive></my-directive>
下面是我的单元测试:

describe('Directive: myDirective', function() {
    var $compile, $scope, $log;

    beforeEach(function() {
        // Load template using a Karma preprocessor (http://tylerhenkel.com/how-to-test-directives-that-use-templateurl/)
        module('views/directives/my-directive.html');
        module('demoApp.directives');
        inject(function(_$compile_, _$rootScope_, _$log_) {
            $compile = _$compile_;
            $scope = _$rootScope_.$new();
            $log = _$log_;
            spyOn($log, 'log');
        });
    });

    it('should work', function() {
        var el = $compile('<my-directive></my-directive>')($scope);
        console.log('Isolated scope:', el.isolateScope());
        el.isolateScope().save();
        expect($log.log).toHaveBeenCalled();
    });
});
descripe('Directive:myDirective',function(){
var$compile,$scope,$log;
beforeach(函数(){
//使用Karma预处理器加载模板(http://tylerhenkel.com/how-to-test-directives-that-use-templateurl/)
模块('views/directions/my directive.html');
模块(“demoApp.Directions”);
注入(函数($compile,$rootScope,$log){
$compile=\$compile;
$scope=\$rootScope\$new();
$log=$log;
间谍($log,'log');
});
});
它('should work',function(){
var el=$compile(“”)($scope);
log('IsolatedScope:',el.isolateScope());
el.isolateScope().save();
expect($log.log).toHaveBeenCalled();
});
});
但是当我打印出隔离范围时,它会导致
未定义
。但真正让我困惑的是,如果我在指令中使用
templateUrl
而不是
templateUrl
,那么一切都可以正常工作:
isolateScope()
有一个完全
scope
对象作为其返回值,一切都很好。然而,不知何故,当使用
templateUrl
时,它会崩溃。这是
ng mocks
中的bug还是Karma预处理器中的bug


提前谢谢。

我也有同样的问题。似乎在调用
$compile(element)($scope)
并使用
模板URL
时,摘要循环不会自动启动。因此,您需要手动设置它:

it('should work',function(){
var el=$compile(“”)($scope);
$scope.$digest();//确保传播更改
log('IsolatedScope:',el.isolateScope());
el.isolateScope().save();
expect($log.log).toHaveBeenCalled();
});

我不知道为什么
$compile
函数不能为您做到这一点,但它一定与
templateUrl
的工作方式有某种特殊性,因为如果您使用内联模板,您不需要调用
$scope.$digest()

isolateScope()之前,我必须模拟并刷新
$httpBackend
已定义。请注意,
$scope.$digest()
没有任何区别

指令:

app.directive('deliverableList', function () {
    return {
        templateUrl: 'app/directives/deliverable-list-directive.tpl.html',
        controller: 'deliverableListDirectiveController',
        restrict = 'E',
        scope = {
            deliverables: '=',
            label: '@'
        }
    }
})
测试:

it('should-defined',inject(函数($rootScope,$compile,$httpBackend){
var scope=$rootScope.$new();
$httpBackend.expectGET('app/directions/deliverable list directive.tpl.html').respond();
变量$element=$compile(“”)(范围);
$httpBackend.flush();
$httpBackend.VerifyNoOutstandingExpection();
$httpBackend.verifyNoOutstandingRequest();
expect($element).toBeDefined();
expect($element.controller).tobededefined();
scope=$element.isolateScope();
expect(scope.toBeDefined();
expect(scope.label).toEqual(“测试”);
expect(数组的scope.instanceof).toEqual(true);
预期(范围、可交付成果、长度)toEqual(1);
expect(scope.deliveries[0]).toEqual({id:123});
}));

我在Angularjs 1.3中使用Angular1.3。

如果在应用程序配置中禁用
debugInfoEnabled

$compileProvider.debugInfoEnabled(false);

isolateScope()
还返回
未定义的

在我的例子中,当我试图在没有隔离作用域属性的指令上隔离作用域时,我经常遇到这种情况

function testDirective() {
  return {
    restrict:'EA',
    template:'<span>{{ message }}</span>'
    scope:{} // <-- Removing this made an obvious difference
  };
}
function testWithoutIsolateScopeDirective() {
  return {
    restrict:'EA',
    template:'<span>{{ message }}</span>'
  };
}
describe('tests pass', function(){
  var compiledElement, isolatedScope, $scope;
  beforeEach(module('test'));
  beforeEach(inject(function ($compile, $rootScope){
    $scope = $rootScope.$new();
    compiledElement = $compile(angular.element('<div test-directive></div>'))($scope);
    isolatedScope = compiledElement.isolateScope();
  }));
  it('element should compile', function () {
    expect(compiledElement).toBeDefined();
  });
  it('scope should isolate', function () {
    expect(isolatedScope).toBeDefined();
  });
});
describe('last test fails', function(){
  var compiledElement, isolatedScope, $scope;
  beforeEach(module('test'));
  beforeEach(inject(function ($compile, $rootScope){
    $scope = $rootScope.$new();
    compiledElement = $compile(angular.element('<div test-without-isolate-scope-directive></div>'))($scope);
    isolatedScope = compiledElement.isolateScope();
  }));
  it('element should compile', function () {
    expect(compiledElement).toBeDefined();
  });
  it('scope should isolate', function () {
    expect(isolatedScope).toBeDefined();
  });
});
函数testDirective(){
返回{
限制:'EA',
模板:“{message}}”
作用域:{}/您可以配置插件。它将HTML模板转换为javascript字符串,并将其放入Angular的
$templateCache
服务中

在配置中设置
moduleName
后,您可以在测试中声明该模块,然后您的所有生产模板都将可用,而无需到处使用
$httpBackend
模拟它们

beforeEach(module('partials'));

您可以在这里找到如何设置插件:

我想它应该是module('views/directives/my directive.html');而不是module('views/directives/my directive');…哎哟!在我的测试中已经有了扩展,在我上面的示例中更正了它。遇到了同样的问题。el.isolateScope()返回'undefined'注意,您必须调用$digest()在rootScope上,否则这将不会非常有用-这解决了我的问题,我使用的是Angular 1.3。此解决方案导致使用空白模板编译指令
function testDirective() {
  return {
    restrict:'EA',
    template:'<span>{{ message }}</span>'
    scope:{} // <-- Removing this made an obvious difference
  };
}
function testWithoutIsolateScopeDirective() {
  return {
    restrict:'EA',
    template:'<span>{{ message }}</span>'
  };
}
describe('tests pass', function(){
  var compiledElement, isolatedScope, $scope;
  beforeEach(module('test'));
  beforeEach(inject(function ($compile, $rootScope){
    $scope = $rootScope.$new();
    compiledElement = $compile(angular.element('<div test-directive></div>'))($scope);
    isolatedScope = compiledElement.isolateScope();
  }));
  it('element should compile', function () {
    expect(compiledElement).toBeDefined();
  });
  it('scope should isolate', function () {
    expect(isolatedScope).toBeDefined();
  });
});
describe('last test fails', function(){
  var compiledElement, isolatedScope, $scope;
  beforeEach(module('test'));
  beforeEach(inject(function ($compile, $rootScope){
    $scope = $rootScope.$new();
    compiledElement = $compile(angular.element('<div test-without-isolate-scope-directive></div>'))($scope);
    isolatedScope = compiledElement.isolateScope();
  }));
  it('element should compile', function () {
    expect(compiledElement).toBeDefined();
  });
  it('scope should isolate', function () {
    expect(isolatedScope).toBeDefined();
  });
});
beforeEach(module('partials'));