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% 适合我,因为组件测试看起来不完整,因为我无法在该上下文中测试大部分功能。
话虽如此,这个问题也促使我考虑将组件分解成更小的组件,以便可以更轻松地隔离和测试一些专用逻辑。然后我可以测试各个组件的功能,而不必担心数据是如何加载的(直接加载还是通过关系异步加载等)。
验收测试确实让我可以测试所有这些小组件的整体集成,所以在进一步分解之后,如果有事件发生,那就太好了。
我在我的组件模板中使用 {{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% 适合我,因为组件测试看起来不完整,因为我无法在该上下文中测试大部分功能。
话虽如此,这个问题也促使我考虑将组件分解成更小的组件,以便可以更轻松地隔离和测试一些专用逻辑。然后我可以测试各个组件的功能,而不必担心数据是如何加载的(直接加载还是通过关系异步加载等)。
验收测试确实让我可以测试所有这些小组件的整体集成,所以在进一步分解之后,如果有事件发生,那就太好了。