EmberJS 2.13单元测试:在运行循环中包装同步代码?

时间:2017-05-04 23:55:50

标签: ember.js ember-data ember-testing

在目前的Ember文档中重复了几次,所以我觉得我必须遗漏一些东西。我们来看simplest example I found

为什么对levelUp的调用被认为是异步的,以保证在运行循环中包装它? incrementProperty是同步的,据我所知,set也是如此(但我可能会在这里弄错)

player.js

import DS from 'ember-data';

export default DS.Model.extend({
  level:     DS.attr('number', { defaultValue: 0 }),
  levelName: DS.attr('string', { defaultValue: 'Noob' }),

  levelUp() {
    let newLevel = this.incrementProperty('level');
    if (newLevel === 5) {
      this.set('levelName', 'Professional');
    }
  }
});

玩家test.js

import { moduleForModel, test } from 'ember-qunit';
import Ember from 'ember';

moduleForModel('player', 'Unit | Model | player', {
  // Specify the other units that are required for this test.
  needs: []
});

test('should increment level when told to', function(assert) {
  // this.subject aliases the createRecord method on the model
  const player = this.subject({ level: 4 });

  // wrap asynchronous call in run loop
  Ember.run(() => player.levelUp());

  assert.equal(player.get('level'), 5, 'level gets incremented');
  assert.equal(player.get('levelName'), 'Professional', 'new level is called professional');
});

2 个答案:

答案 0 :(得分:2)

首先,你是绝对正确的。在指南的任何地方都没有详细描述。

在测试模式下,禁用自动运行。您可以从the guides进一步了解这一点。

更改模型中的值会触发一个运行循环。您可以在this twiddle看到它。结果是:

  

断言失败:您已打开测试模式,禁用了   run-loop的自动运行。您将需要使用异步包装任何代码   跑步中的副作用

(顺便说一句,setincrementProperty都会触发此运行循环作为您的猜测。)

然后这是运行循环源:

  1. DS.attr返回computed property with set
  2. set函数triggers an event
  3. 最后,a run loop is triggered

答案 1 :(得分:1)

@ykaragol在他的正确答案中对他的解释是绝对正确的,我没有任何补充,为什么你需要在运行循环中包装你的代码;因为源代码在那里并且正在调用emberRun.schedule,这需要一个运行循环。

我想解释的更多是关于你得到的断言错误:“你已经打开了测试模式,它禁用了运行循环的自动运行。你将需要包含任何带有异步副作用的代码。跑”。这并不直接意味着异步操作(在进行ajax调用或触发定时器的意义上)就位。我们大多不知道但是; Ember.js确实使用Ember.run循环和各种运行队列,例如syncactionsrenderafterRender等,以便安排效果我们的代码,以优化我们的应用程序的呈现。即使代码this.set('levelName', 'Professional');确实看起来非常同步; Ember将其包装在运行循环中,以便计算属性计算或其他更新被缓冲在一起,以防止模板的多次渲染(从而降低性能)。

我只希望有更好的解释,包括运行循环,运行队列,或者如何以及为什么在测试中使用运行循环,但是没有:(