2014-02-22 31 views
0

我想测试一个Angular指令,我不知道为什么我的测试没有通过。我真的很感激一些额外的眼睛帮助我解决这个问题。Angular指令测试未通过,但在浏览器中运行。怀疑jqlite是罪魁祸首

下测试该指令是验证指令,将验证元素的值是否与通过属性传递的ID匹配元素:

angular.module('app') 
    .directive('mustMatch', -> 
    restrict: 'A' 
    require: 'ngModel' 
    link: (scope, element, attrs, ctrl) -> 
     # I've tried both of these, traversal vs selection, neither work under test 
     #matchedElement = element.parents('form').find attrs.mustMatch 
     matchedElement = $(attrs.mustMatch) 

     ctrl.$parsers.unshift (val) -> 
     if val is matchedElement.val() 
      ctrl.$setValidity 'mustMatch', true 
      return val 
     else 
      ctrl.$setValidity 'mustMatch', false 
      return undefined 
) 

这里是我的测试设置:

describe 'Directive: mustMatch', -> 
    scope = null 
    element = null 
    form = null 

    beforeEach module 'app' 

    beforeEach inject ($compile, $rootScope) -> 
    scope = $rootScope.$new() 
    scope.model = text1: '', text2: '' 
    element = angular.element '''<form name="someForm"> 
     <input type="text" name="text1" ng-model="model.text1" id="text1"/> 
     <input type="text" name="text2" ng-model="model.text2" must-match="#text1"/> 
     </form>''' 
    $compile(element)(scope) 
    scope.$digest() 
    form = scope.someForm 

    it 'should fail validation if values do not match', -> 
    form.text1.$setViewValue 'some text' 
    form.text2.$setViewValue 'some other text' 
    expect(scope.model.text2).toBe undefined 
    expect(form.text2.$valid).toBe false 

    # TODO: Why isn't this passing? Is the matched element not being found? 
    it 'should pass validation if values match', -> 
    value = 'some text' 
    form.text1.$setViewValue value 
    form.text2.$setViewValue value 
    expect(scope.model.text2).toBe value 
    expect(form.text2.$valid).toBe true 

第一次测试通过很好,但第二次测试返回undefined/false,未能达到测试的预期。 同样,该指令在浏览器中工作得很好,但第二次单元测试给我提供了一些问题。

我在我的karma.conf.js文件中有jQuery,因为我的应用程序依赖于Bootstrap和一些其他jQuery插件。我有其他使用这种方法的指令测试。我的理论是指令中的元素选择在测试中不能正常工作。我在吠叫正确的树吗?还有什么我失踪?

在此先感谢!

更新

仍运行到问题,但我相信我已经分离出的问题给DOM遍历我做得到匹配的元素。如果我更换这行指令的逻辑函数的...

if val is matchedElement.val() 

...这条线......

if val is 'some text' 

我可以让测试通过。所以这告诉我,链接函数的参数element的值可能不是我在测试时期待它的值。

回答

0

在浪费了几个小时后,我把头发拉出来,尝试不同的修复方法,我偶然发现了我的问题的答案。我的问题是在beforeEach函数。 我没有将model.text1设置为我期望验证的值。这是我的更新测试:

describe 'Directive: mustMatch', -> 
    scope = null 
    element = null 
    form = null 

    beforeEach module 'app' 

    beforeEach inject ($compile, $rootScope) -> 
    scope = $rootScope.$new() 

    # Setting `model.text1` to 'some text' fixed my problem 
    scope.model = text1: 'some text', text2: '' 

    element = angular.element '''<form name="someForm"> 
     <input type="text" name="text1" ng-model="model.text1" id="text1" /> 
     <input type="text" name="text2" ng-model="model.text2" id="text2" must-match="#text1" /> 
     </form>''' 
    $compile(element)(scope) 
    scope.$digest() 
    form = scope.someForm 
    form.text1.$setViewValue 'some text' 

    it 'should fail validation if values do not match', -> 
    form.text2.$setViewValue 'some other text' 
    expect(scope.model.text2).toBe undefined 
    expect(form.text2.$valid).toBe false 

    it 'should pass validation if values match', -> 
    form.text2.$setViewValue 'some text' 
    expect(scope.model.text2).toBe 'some text' 
    expect(form.text2.$valid).toBe true 
相关问题