Ember 集成测试 + 具有关系的模拟模型 + ember-deferred-content 附加组件

Ember integration test + mocking model with relationships + ember-deferred-content add-on

我在我的组件模板中使用 {{deferred-content}} 组件,挂接到模型对象的 asset 关系中。这是我正在尝试做的精简版:

{{#unless showUploadForm}}
  {{#deferred-content contentBlock.asset as |d|}}
    {{#d.fulfilled as |asset|}}
      {{#if asset.asset.isProcessing}}
        {{! Show processing message here }}
      {{/if}}
    {{/d.fulfilled}}
  {{/deferred-content}}
{{/unless}

showUploadForm 计算出的 属性 很有趣:

showUploadForm: computed('contentBlock.asset', 'isReplacing', function() {
  console.log(this.get('contentBlock.asset.id'));
  return this.get('isReplacing') || isBlank(this.get('contentBlock.asset.id'));
})

这一切在我的开发模式和生产模式下的应用程序中都非常有效,都挂接到 API 等等。

然后在我尝试编写集成测试时进入Trouble Town:

test('it displays processing message when asset is loaded in with processing status', function(assert) {
  let deferred = RSVP.defer();

  this.set('contentBlock', Ember.Object.create({
    asset: deferred.promise
  }));

  this.render(hbs`{{asset-editor contentBlock=contentBlock}}`);

  // This is likely the big fat problem. I don't know what to put here.
  deferred.resolve(Ember.Object.create({
    id: 'the-id',
    asset: {
      isProcessing: true
    }
  }));

  let done = assert.async();

  return wait().then(() => {
    // Stuff I'm asserting is here. It fails because the
    // `showUploadForm` computed property is returning `true`.
    done();
  });
});

有趣的部分在我上面分享的计算 属性 中。在 development/production 中,我得到一个 id。在测试中,我得到 undefined.

我确定这个问题是因为 Ember 数据在解析接收到的数据后如何处理它 "unpacks" 的承诺和对象。问题是我不知道如何在我的集成测试中模拟它。

在调用 deferred.resolve 以强制应用程序将值视为模型关系时,我可以设置什么吗?

奖励: 为了咯咯笑,我把 Ember Mirage 连接到测试中,查询 store 服务以获取 contentBlock(两者侧加载相关数据,然后不加载),并将其设置为 contentBlock 在测试上下文中。我得到了类似的结果。

我最终通过验收测试而不是集成测试来解决这个问题。这并不是 100% 适合我,因为组件测试看起来不完整,因为我无法在该上下文中测试大部分功能。

话虽如此,这个问题也促使我考虑将组件分解成更小的组件,以便可以更轻松地隔离和测试一些专用逻辑。然后我可以测试各个组件的功能,而不必担心数据是如何加载的(直接加载还是通过关系异步加载等)。

验收测试确实让我可以测试所有这些小组件的整体集成,所以在进一步分解之后,如果有事件发生,那就太好了。