【问题标题】:Jasmine test fails with error from a different suiteJasmine 测试因来自不同套件的错误而失败
【发布时间】:2016-02-08 19:51:18
【问题描述】:

在 karma-jasmine 测试 Angular 应用程序时体验到一些特殊行为。

在一个报告失败的套件中进行测试,但消息来自另一个测试套件文件中的单独测试。

测试结果:

factory: page should uncheck all items FAILED
  Expected undefined to contain '<div class="ui-select-container ui-select-bootstrap dropdown ng-valid" ng-class="{open: $select.open}" ng-model="test.slctbx.selected" theme="bootstrap" ng-disabled="disabled"></div>'

那个测试实际上是:

describe 'factory: page', () ->

...

  it 'should check all items', () ->
    Page.checkAll null

    expect(Page.actions).toEqual {checkAll: false}

错误其实来自:

describe 'directive: select', () ->

  ...

  it 'should replace select box', () ->
    replacementMarkup = '<div class="ui-select-container ui-select-bootstrap dropdown ng-valid" ng-class="{open: $select.open}" ng-model="test.slctbx.selected" theme="bootstrap" ng-disabled="disabled"></div>'

    setTimeout () ->
      expect($('select').length).toEqual 0
      expect($('form').html()).toContain replacementMarkup
      return
      , 0

如果我删除 factory: page suite 这个行为只是存在但另一个测试套件。

超时很臭,但这只是因为该指令中有一个超时等待任意时间,因此它即将替换的元素已被填充......(这本身有点臭!)

==== EDIT + 指令代码 ====

link: (scope, element, attrs) ->

  items       = []
  name        = element.attr('name').replace '[]', ''
  placeholder = ''

  for index, el of element.find('option') when typeof el is 'object' and index isnt '0'
    if index == '1'
      placeholder = el.innerHTML
    else if typeof el[0] == 'undefined'
      items.push {value: el.getAttribute('value'), label: el.innerHTML}

  if typeof scope.$parent.test != 'object'
    scope.$parent.test = {}

  scope.$parent.test[name] = items

  select = '<ui-select ng-model="test.' + name + '.selected" theme="bootstrap" ng-disabled="disabled">
    <ui-select-match placeholder="' + placeholder + '">{{ $select.selected.label }}</ui-select-match>
    <ui-select-choices repeat="item in test[\'' + name + '\'] | filter: $select.search">
        <div ng-bind-html="item.label | highlight: $select.search"></div>
    </ui-select-choices>
</ui-select>'

  newSel = $compile(select)(scope.$parent)

  setTimeout () ->
    element.replaceWith angular.element(newSel)
  , 10


  return false

【问题讨论】:

  • 为什么不把整个select 变量值作为template 并将replace 设置为true?您可能有兴趣阅读thisthat
  • 是的 - 老实说,我不知道为什么会这样,但我对重构和让事情变得更好并不感到难过 - 会给这个打击。 ty

标签: angularjs unit-testing coffeescript jasmine


【解决方案1】:

为什么不在指令和测试中都使用$timeout 而不是setTimeout()?您可以在测试中使用$timeout.flush() 来验证指令是否等待了任意时间 而无需等待。

你的指令应该使用$timeout(func, arbitraryAmountOfTime)而不是setTimeout(func, arbitraryAmountOfTime)然后测试变成:

it 'should replace select box', ->
  inject ($timeout) ->
    $timeout.flush()
    expect($('select').length).toEqual 0
    expect($('form').html()).toContain replacementMarkup

我想在当前代码中,jasmie 继续进行下一个测试,然后您的超时调用突然出现,导致当前正在执行的测试失败。但这只是一种预感。

【讨论】:

  • 感谢您的回复。它尝试了但无济于事:(我认为问题在于指令本身(我没有写它,但我必须做改装测试)我添加到 OP 的违规代码 - 如果可以改进,请大家好我很想摆脱那里的超时......
猜你喜欢
  • 1970-01-01
  • 2015-11-12
  • 2014-01-06
  • 1970-01-01
  • 2021-09-08
  • 2018-06-29
  • 2023-03-08
  • 1970-01-01
  • 2013-08-06
相关资源
最近更新 更多