【问题标题】:Angular directive test not passing, but works in browser. Suspecting jqlite to be the culpritAngular 指令测试未通过,但可以在浏览器中使用。怀疑jqlite是罪魁祸首
【发布时间】:2014-02-22 18:01:15
【问题描述】:

我正在尝试测试一个 Angular 指令,但我不确定为什么我的测试没有通过。我真的很感激能有几双眼睛帮助我弄清楚这一点。

被测指令是一个验证指令,它将验证元素的值是否与通过属性传入的 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 参数的值可能不是我在测试时所期望的值。

【问题讨论】:

    标签: angularjs unit-testing coffeescript angularjs-directive


    【解决方案1】:

    在浪费了几个小时扯掉我的头发并尝试了不同的修复后,我偶然发现了我的问题的答案。我的问题出在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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      相关资源
      最近更新 更多