Ember验收测试没有看到更新的DOM

时间:2016-09-20 07:20:27

标签: ember.js acceptance-testing

我还在深入了解Ember的验收测试。我似乎一直存在的一个问题是DOM在事件发生后没有得到更新。例如,我的页面有一个侧边菜单。一个简单的切换改变了它的组件中的属性,然后切换菜单本身的“隐藏”类:

组件

import Ember from 'ember';

export default Ember.Component.extend({
  menuHidden: true,
  actions: {
    toggleMenu(){
      this.set('menuHidden', !this.get('menuHidden'));
    },
  }
});

模板

<a id="menu-toggle" class="{{unless menuHidden 'open'}}" {{ action 'toggleMenu' }}>
  <span></span><span></span><span></span>
</a>
<div id="menu" class="{{if menuHidden 'hide'}}">
  {{#link-to 'dashboard' invokeAction='closeMenu'}}Dashboard{{/link-to}}
  {{#each menu as |child|}}
    {{menu-child child=child createCase=(action 'createCase') menuHidden=menuHidden}}
  {{/each}}
  <a href="javascript:void(0)" {{ action 'logout' }}>Logout</a>
</div>

验收测试

import { test } from 'ember-qunit';
import moduleForAcceptance from '../helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | side menu');

test('side menu opens and closes', assert=>{

  logIn('my@email.com', 'password');

  andThen(()=>{
    assert.equal(find('#menu').attr('class'), 'hide', 'Hidden by default');

    click('#menu-toggle');

    andThen(()=>{
      assert.equal(find('#menu').attr('class'), '', 'Now visible');
    });
  });

});

现在这在浏览器中正常运行。测试使用我的自定义帮助程序正常登录(菜单仅在登录时可见),如果我将console.log放入toggleMenu(),则测试会触发它。但它失败了最后assert。我在最后一个assert之前在菜单的包装器HTML上完成了一个console.log,它仍然看到#menu元素class=hide

有什么明显我做错了吗?我找不到很多在验收测试中有多个andThen调用的人的例子,所以我尝试将其嵌套 - 如上所述 - 并将第二个andThen拉出第一个内联。没有区别。

1 个答案:

答案 0 :(得分:0)

如果您在测试浏览器窗口中打开开发人员控制台,则可能会看到此错误:

Assertion failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run

组件中的以下行被视为具有异步副作用的代码:

this.set('menuHidden', !this.get('menuHidden'));

相反,要使测试起作用,您需要手动将行添加到运行循环中,这可以通过在Ember.run中添加该行代码来实现,如下所示:

import Ember from 'ember';

export default Ember.Component.extend({
  menuHidden: true,
  actions: {
    toggleMenu(){
      Ember.run(this, function(){
        this.set('menuHidden', !this.get('menuHidden'));
      });
    },
  }
});

这不会影响实际运行的代码,因为Ember.run中的操作将合并到主运行循环中。

我有一个类似的问题,我在完成here

中提到的步骤后设法解决了这个问题