【问题标题】:Angular Testing Directive with templateUrl & isolate scope带有 templateUrl 和隔离范围的 Angular 测试指令
【发布时间】:2015-02-26 03:55:18
【问题描述】:

angular.js 的新手,不知道如何为具有 templateUrl 和隔离范围的指令编写测试。

这是我的控制器

(function(){
angular.module('buttons')
    .controller('buttonController', ['$scope', function($scope){

        //primary button
        $scope.primaryButton = { name: 'Submit'};
})();

这是我的观点 index.html &

<div class="layoutLeft">
        <p>Primary Button</p>
        <primary-button info="primaryButton"></primary-button>
    </div>

primary-button.html

<button class="{{buttonInfo.class}}">{{buttonInfo.name}}</button>

这是我的指令

(function(){
    angular.module('buttons')
        .directive('primaryButton', function() {
            return {
                restrict: 'EA',
                scope: {
                    buttonInfo: '=info'
                },
                templateUrl: 'scripts/local/views/primary-button.html'
            }
        })
    })();

这是我的测试

(function(){
    beforeEach(angular.mock.module('buttons'));
describe('Buttons Directive Test', function(){

    var $compile, $scope, $httpBackend;

    beforeEach(module('templates'));

    beforeEach(inject(function(_$compile_, _$rootScope_) {
        $compile = _$compile_;
        $scope = _$rootScope_.$new();

        $scope.primaryButton = {name: 'Save'};

        elm = angular.element("<primary-button info='buttonInfo'></primary-button>");
        e = $compile(elm)($scope);
        e.digest();
    }));

    it('should do something', function(){
        expect(e.html()).toContain($scope.primaryButton);
    });
});

})();

我正在使用 jasmine 和 karma 进行测试,有人可以指导我做错了什么

【问题讨论】:

  • 我的解决方案是否解决了您的问题?请告诉我。

标签: javascript angularjs jasmine karma-jasmine


【解决方案1】:

编辑:这是一个 plunkr 演示非常接近您的代码在做什么。您的问题中的代码存在多个问题,我已修复:

http://plnkr.co/edit/QXprEUof2Ps0Vivg4L34?p=preview

  1. 在您的测试中调用 e.digest(),这将不起作用,因为您无法消化元素...您应该调用 $scope.$digest。
  2. e.html() 将不包含该 JSON blob。我将此解释为希望它包含名称标签...
  3. info='buttonInfo' 将 info 绑定到外部作用域中的属性 buttonInfo,但您将其称为 'primaryButton'。将 $scope.primaryButton 重命名为 $scope.buttonInfo
  4. 在注入 compile、rootscope 时,您使用了一些并非完全必要的下划线,但这没什么大不了的
  5. 我使用了内联模板而不是仅为 plunkr 加载它,但加载它并没有错
  6. 因为您的指令是一个元素,所以我添加了“替换”,它用一个直按钮替换了该元素。请考虑将其改为属性。

我的 plunkr 通过了 jasmine 测试按钮的工作演示。如果您需要更多帮助,请告诉我。祝 AngularJS 好运。

(旧答案)

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

您将需要使用 nghtml2js 之类的东西来加载您的模板并通过模板缓存使它们可用。

using nghtml2js

这是您的第一个问题。您的第二个问题是通过在元素编译后调用isolateScope() 来获得隔离范围。记录在 elem 上调用它的结果,你会找到你所追求的属性。

e.isolateScope()

【讨论】:

  • 我正在使用 karma config 和 nghtml2js 加载 html 文件,我将尝试使用isolateScope()
  • 成功了吗?这就是让你的隔离范围出来的方法。 stackoverflow.com/questions/17371836/…
  • 嘿,我已经为你创建了一个 plunkr,请看一下。
【解决方案2】:

不遵循上述答案被标记为接受的原因。该问题询问如何使用 templateUrl 来完成,而 @PeterAshwell 的回答提供了一个内联 HTML 在使用 templateUrl 时不起作用的解决方案。

要在使用 templateUrl 时获得对隔离作用域的访问权限,您必须在 $timeout 中包装 isolateScope 调用,以允许 $http 调用(由 templateUrl 进行)完成。

代码看起来像:

element = $compile("<myHTML />")($scope)

$timeout(function() {
     expect(element.isolateScope().myProp).toEqual(12);

}), 0 , false);

$timeout.flush();

【讨论】:

  • 好答案!我还认为添加 $apply() 以确保解决任何未完成的承诺是个好主意。
猜你喜欢
  • 2015-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 2014-12-13
  • 1970-01-01
相关资源
最近更新 更多