Testing 如何在Ember测试中断言运行循环DOM更改

Testing 如何在Ember测试中断言运行循环DOM更改,testing,ember.js,Testing,Ember.js,我正在为Ember 1.6中编写的Ember应用程序编写测试 在控制器内,我在承诺成功后执行一个函数: var me = this; function onSuccess(result) { printSuccessMessage(); Ember.RSVP.all(promises).then(function(value) { Ember.run.later(this, function() { clearMessages();

我正在为Ember 1.6中编写的Ember应用程序编写测试

在控制器内,我在承诺成功后执行一个函数:

var me = this;

function onSuccess(result) {

    printSuccessMessage();

    Ember.RSVP.all(promises).then(function(value) {
        Ember.run.later(this, function() {
            clearMessages();
        }, 5000);
    });
}
然后,在测试中,我试图断言出现了成功消息:

    fillIn('#MyInputField', 'Some text');
    click('#MyButton');

    andThen(function() {
        strictEqual(find('[data-output="info-message"]').text().trim().indexOf('Done!') >= 0, true, 'Expected success message!');
    });
但问题是,在单击之后,
正在等待运行循环完成。因此,在单击之后,
然后等待5秒钟,然后执行断言

此时已执行
clearMessages()
,清除消息div,测试失败


知道如何断言此消息具有特定文本吗?

如果您愿意在代码中设置一个条件,检查Ember是否处于测试模式,您可以在测试中切换
Ember.testing
值,然后根据该值清除或不清除控制器中的消息。然后,您的测试可以断言消息在一个实例中被清除,并在另一个实例中显示

在控制器的
onSuccess
调用中,观察
Ember.testing
条件:

onSuccess(message) {
  this.printSuccessMessage(message);

  if (Ember.testing) { // <-- HERE
    // during testing
    return; // don't clear the message and assert that it's there
  } else {
    // during dev, live in production, or Ember.testing === false
    this.clearMessages(); // clear the message, and assert that it's gone
  }  
},
在接下来的测试中,观察
Ember.testing
false
切换,这将“模拟”控制器的实时开发或生产条件。控制器将正常清除该消息,并且该测试也将成功:

test('clearing the message', function(assert) { 
  visit('/messages');
  fillIn('input.text-input', 'Some text');

  andThen(() => {
    Ember.testing = false;
  });

  click('button.clicker');

  // while Ember.testing is `false`, remove message, as normal, as in dev or prod
  andThen(() => {
    assert.equal(find('div.info-message').text(), 
                 '', 
                 'The message has been cleared.'); 
  });

  // reset Ember.testing to its default
  andThen(() => {
    Ember.testing = true;
  });
});
请注意,
Ember.testing
将在不再需要
false
条件时重置为其默认值
true
。这很重要,因为

在这个解决方案中,对一些代码进行了重构,以隔离关注点并使单元测试更容易。这是一个值得展示的例子,它的部分灵感来自于此

test('clearing the message', function(assert) { 
  visit('/messages');
  fillIn('input.text-input', 'Some text');

  andThen(() => {
    Ember.testing = false;
  });

  click('button.clicker');

  // while Ember.testing is `false`, remove message, as normal, as in dev or prod
  andThen(() => {
    assert.equal(find('div.info-message').text(), 
                 '', 
                 'The message has been cleared.'); 
  });

  // reset Ember.testing to its default
  andThen(() => {
    Ember.testing = true;
  });
});