【问题标题】:Testing an attribute of isolated scope from a directive从指令中测试隔离范围的属性
【发布时间】:2014-12-13 03:01:15
【问题描述】:

我已经检查了this 与指令隔离范围相关的问答,它帮助我解决了测试使用'@' 属性的属性的问题;但我发现很难测试使用 '=' 属性的属性。

考虑(来自我的指令即将到来):

return {
        restrict: 'A',
        link: link,
        scope: {
            upcoming: '@',
            patientDetails: '='
        }
     };

在我对upcoming 的测试中,我可以使用isolateScope() 函数访问它(从角度1.2 开始),如下所示:

    elm = angular.element('<div upcoming="remembered" patient-details="patientDetails"></div>');

    // Compiles the directive and links it to the scope
    $compile(elm)(scope);
    scope.$digest();
    isolateScope = elm.isolateScope();

在测试中我可以这样做:

it("should have attribute 'upcoming' attached to isolate scope", function () {
    expect(isolateScope.upcoming).toBeDefined();
    expect(isolateScope.upcoming).toBe('remembered');
});

但是,如果我以相同的方式处理其他属性,则会收到 undefined 错误。然后我尝试了这个:

 // Retrieve the target html - remembered.html
beforeEach(inject(function ($compile) {
    patient = {
        name: 'Lorem Ipsum',
        readyForRefill: 1,
        progressCount: 2,
        upcomingCount: 3,
        taggedCount: 4,
        expiringCount: 5,
        oneRefillRemaining: 9000
    };
    elm = angular.element('<div upcoming="remembered" patient-details="patient"></div>');

    // Compiles the directive and links it to the scope
    $compile(elm)(scope);
    scope.$digest();
    isolateScope = elm.isolateScope();
    isolateScope.patientDetails = patient;
}));

测试:

it("should have attribute 'patientDetails' attached to isolate scope", function () {
    expect(isolateScope.patientDetails).toBeDefined();
});

通过了,但我觉得这是在测试错误的东西。

谁能帮我澄清一下?

编辑

按照 tasseKATT 的建议解决了问题,但确实打破了其他 5 项测试。这些测试基本上检查了正在加载的实际模板并确定它们具有哪些内容。例如:

it("ul should contain 4 li", function () {
    var li = elm.find('li');
    expect(li.length).toBe(4);
});

不再有效,因为 elm 元素现在是 &lt;div upcoming="remembered" patient-details="patient"&gt;&lt;/div&gt; html,而不是通过模板加载的那个:

<p><a href=""><b>Sign in</b></a> to view your full <br>prescription statuses.</p>
<ul>
    <li><span>{{patientDetails.readyForRefill}}</span> Prescriptions Ready for Refill</li>
    <li><span>{{patientDetails.readyForRefill}}</span> ReadyFill<sup>&#174;</sup> 
    <li><span>{{patientDetails.expiringCount}}</span> Expiring Prescriptions</li>
    <li><span>{{patientDetails.oneRefillRemaining}}</span> Prescriptions with 1 Refill Left</li>
</ul>

是否可以正确加载两者?尽管值得注意的是,根据谁登录,模板会发生变化,所以这是否会使任何计算 div 和 p 标签的尝试与测试无关?

谢谢

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    如果您想确保指令的范围通过正确的患者详细信息对象,您应该在编译元素之前将其放入范围中。然后您可以通过isolateScope() 检索它并执行您的验证。

    例如:

    elm = angular.element('<div upcoming="remembered" patient-details="patient"></div>');
    
    scope = $rootScope.$new();
    
    scope.patient = {
      name: 'Lorem Ipsum',
      readyForRefill: 1,
      progressCount: 2,
      upcomingCount: 3,
      taggedCount: 4,
      expiringCount: 5,
      oneRefillRemaining: 9000
    };
    
    $compile(elm)(scope);
    isolateScope = elm.isolateScope();
    

    还有:

    it("should work", function() {
      expect(isolateScope.patientDetails).toBeDefined();
      expect(isolateScope.patientDetails.name).toBe('Lorem Ipsum');
    });
    

    更新:

    如果你真的需要测试生成的标记,你应该使用编译的元素:

    compiled = $compile(elm)(scope);
    
    ...
    
    it("ul should contain 4 li", function () {
        var li = compiled.find('li');
        expect(li.length).toBe(4);
    });
    

    【讨论】:

    • 这确实解决了我的问题,但碰巧破坏了其他一些测试 - 请参阅我对它所做的编辑
    • 我按照你说的做了,但是基于之前所做的更正,测试仍然失败 - 为了解决这个问题,我必须以以前的方式加载它,但创建一个不同的元素来容纳它 - 很好还是不好?
    • 很难说没有看到全貌。我的第一个答案与您在问题中使用的元素相同,所以我真的不明白它如何破坏其他测试。
    猜你喜欢
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    相关资源
    最近更新 更多