在路由更改上使用过滤器时未渲染路由模型
Posted
技术标签:
【中文标题】在路由更改上使用过滤器时未渲染路由模型【英文标题】:Route model not rendered when using filter on route change 【发布时间】:2017-11-17 11:38:21 【问题描述】:我正在尝试在新应用上设置 mirage 以进行测试。
ember-cli: 2.16.2
ember-cli-海市蜃楼:0.4.0
我有一个虚拟测试,只是试图设置 mirage 并验证它是否正常工作。
我会做类似于测试route.model()
的事情。
使用 mirage 的JSONAPISerializer
,我的工厂和 migrage-model 什么都没有。
// models/trip.js
import DS from 'ember-data';
export default DS.Model.extend(
name: DS.attr('string'),
);
我的测试:
import moduleFor, test from 'ember-qunit';
import startMirage from 'frontend/initializers/ember-cli-mirage';
moduleFor('route:trips.index', 'Unit | Route | trips.index',
needs: ['service:session', 'model:trip', 'adapter:application'],
beforeEach()
this.server = startMirage();
,
afterEach()
this.server.shutdown();
);
test('model', function (assert)
let route = this.subject();
this.server.create('trip');
Ember.run(() =>
this.get('store').findAll('trip')
);
assert.ok(route);
);
我收到此错误:
TypeError: Cannot read property 'push' of null
at Class._setupRelationshipsForModel (http://localhost:4200/assets/vendor.js:196482:36)
at Class._pushInternalModel (http://localhost:4200/assets/vendor.js:196473:10)
at http://localhost:4200/assets/vendor.js:196425:20
at Backburner.run (http://localhost:4200/assets/vendor.js:20213:36)
at Backburner.join (http://localhost:4200/assets/vendor.js:20222:33)
at Class._push (http://localhost:4200/assets/vendor.js:196397:50)
at http://localhost:4200/assets/vendor.js:192955:18
at tryCatcher (http://localhost:4200/assets/vendor.js:63559:21)
at invokeCallback (http://localhost:4200/assets/vendor.js:63737:33)
at publish (http://localhost:4200/assets/vendor.js:63723:9)
在开发/生产和使用真实服务器获取数据方面工作良好。
如果我不使用 mirage 创建我的记录,也不例外。
看起来问题只发生在Ember.run
内
删除 Ember.run
不会引发异常,但我需要它来正确测试(并避免像 You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run
这样的错误)...
【问题讨论】:
如果没有Ember.run
也不会引发异常,那为什么还要使用呢?
有时我必须使用Ember.run
,否则我会收到此错误“您已打开测试模式,这禁用了运行循环的自动运行。您需要将任何具有异步副作用的代码包装在跑步”——这是有道理的。
【参考方案1】:
store.findAll
返回一个承诺。尝试解决承诺并在 .then()
中运行您的断言
(忽略这不是测试路线的方法这一事实,但我知道您只是使用此测试来解决您的 mirage 设置)
【讨论】:
谢谢克里斯托弗,很遗憾这不起作用,请在此处查看建议的解决方案:github.com/samselikoff/ember-cli-mirage/issues/… 你能解释一下为什么这不是对路线进行单元测试的好方法吗?是的,这是一个虚拟示例,但我最后所做的是对路由的模型函数返回正确记录进行单元测试。【参考方案2】:正如@rstellar 在此处https://github.com/samselikoff/ember-cli-mirage/issues/1220#issuecomment-350155703 所建议的那样,一个可行的解决方案是在函数周围使用 async/await。
当我们在 store 被销毁后尝试建立关系时会发生此问题。此解决方案将防止这种情况发生,直到函数结束。
这是工作代码:
import moduleFor, test from 'ember-qunit';
import wait from 'ember-test-helpers/wait'; // import wait from ember here
import startMirage from 'frontend/initializers/ember-cli-mirage';
moduleFor('route:trips.index', 'Unit | Route | trips.index',
needs: ['service:session', 'model:trip', 'adapter:application'],
beforeEach()
this.server = startMirage();
,
afterEach()
this.server.shutdown();
);
test('model', async function (assert) // Declare this function as async
let route = this.subject();
this.server.create('trip');
Ember.run(() =>
this.get('store').findAll('trip')
);
assert.ok(route);
await wait(); // The actual wait
);
在 Ember 上打开了一个 PR,以使错误更加明确。
【讨论】:
以上是关于在路由更改上使用过滤器时未渲染路由模型的主要内容,如果未能解决你的问题,请参考以下文章