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

时间:2016-11-29 11:25:40

标签: testing ember.js

我正在为Ember 1.6编写的Ember app编写测试。

在控制器内部,我有一个在承诺成功时执行的功能:

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!');
    });

但问题是,点击后,andThen正在等待运行循环完成。因此,在此单击之后,andThen等待5秒,然后执行断言。

在那一刻clearMessages()已经执行,消息div被清除,测试失败。

知道如何断言此消息有某些文字吗?

1 个答案:

答案 0 :(得分:1)

如果您愿意在代码中有条件,检查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默认为true,控制器不会清除消息,以下测试将成功:

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

  // while Ember.testing is `true` (default), do not remove message
  andThen(() => {
    assert.equal(find('div.info-message').text(),
                 'Done!',
                 'The message was set properly.'); 
  });
});

在接下来的测试中,观察falseEmber.testing的切换,这将“模拟”控制器的实时开发或生产条件。控制器将正常清除消息,此测试也将成功:

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条件,true就会重置为默认值false。这很重要,因为Ember run loop behavior is different during testing by design

在此解决方案中,一些代码已经过重构,以隔离问题并使单元测试更容易。这是一个Ember Twiddle来展示,其中部分受到article on Medium的启发。