如何测试Ember中返回DS.PromiseArray的计算属性?
这个问题我之前也碰到过!核心原因就是测试执行时,DS.PromiseArray还没完成数据加载,计算用户数量的属性还停留在初始值0,而你期望的是异步加载后的3。下面给你几个靠谱的解决方案:
解决方案步骤
1. 先确保后端数据模拟正确
首先要在测试里模拟好3条用户数据(假设你用Ember Mirage做后端模拟),保证请求能返回正确的数据集:
test('用户数量计算属性返回正确值', async function(assert) { // 模拟服务器返回3个用户实例 this.server.createList('user', 3); // 渲染你的组件/路由(这里以组件测试为例) await this.render(hbs`{{your-target-component}}`); // 后续等待异步操作完成再断言 });
2. 等待PromiseArray加载完成再断言
因为DS.PromiseArray是异步的,必须等它的Promise解析后,计算属性才会更新。这里有几种常用的等待方式:
方式一:直接等待计算属性的Promise
如果你的用户数据计算属性(比如叫users)返回的是DS.PromiseArray,可以直接await它的promise属性:
test('用户数量计算属性返回正确值', async function(assert) { this.server.createList('user', 3); const component = await this.render(hbs`{{your-target-component}}`); // 等待用户数据的Promise完成解析 await component.users.promise; // 此时再断言数量 assert.equal(component.userCount, 3, '用户数量计算正确'); });
方式二:通过DOM元素等待更新
如果你的模板里有专门显示用户数量的元素(比如带data-test-user-count属性的标签),可以用Ember的waitFor助手等待元素内容更新:
test('用户数量计算属性返回正确值', async function(assert) { this.server.createList('user', 3); await this.render(hbs`{{your-target-component}}`); // 等待显示数量的元素内容变为3 await this.waitFor('[data-test-user-count]', { text: '3' }); // 断言DOM显示正确 assert.dom('[data-test-user-count]').hasText('3', '用户数量显示正确'); });
方式三:适配旧版Ember测试语法(QUnit 1.x)
如果你的项目还在使用旧的测试语法,可以用andThen来等待异步操作完成:
test('用户数量计算属性返回正确值', function(assert) { assert.expect(1); this.server.createList('user', 3); this.render(hbs`{{your-target-component}}`); // 等待所有异步操作完成 this.andThen(() => { assert.equal(this.$('[data-test-user-count]').text().trim(), '3'); }); });
3. 检查计算属性的依赖是否正确
最后要确认你的用户数量计算属性,正确依赖了用户数据的状态:
// 示例计算属性写法 userCount: computed('users.isFulfilled', 'users.length', function() { // 只有当Promise完成后,才返回实际长度,否则返回0 return this.users.isFulfilled ? this.users.length : 0; })
这样当DS.PromiseArray加载完成后,users.isFulfilled变为true,计算属性会自动重新计算,返回正确的用户数量。
内容的提问来源于stack exchange,提问作者user2605836
相关产品推荐
相关产品推荐

