不幸的是,以干净的方式做到这一点似乎并不容易。
在其内部测试中,Ember 使用bootApplication 指向出现错误的路由(请参阅github)并且能够直接捕获错误。不幸的是,如果您尝试在测试中围绕调用visit 执行任何形式的try/catch 或then/catch,您会发现它失败了。
当您visit 链接导致验收测试出现错误子状态时,Ember 的 defaultActionHandlers.error 将被触发。按照设计,它并不意味着可以被覆盖。它调用logError,它调用Ember.default.Logger.error。
所以要测试这个子状态,我们需要临时覆盖那个方法。我们也可以像这样在 ember 容器内窥视以访问currentRouteName(使用sinon 进行间谍活动):
test('when there is an API error an error message is shown', function(assert) {
const emberLoggerError = Ember.Logger.error;
Ember.Logger.error = sinon.spy();
visit('/users/');
andThen(() => {
// This could be nicer and less private with `getOwner`
let { currentRouteName } = this.application.__container__.lookup('router:main');
assert.equal(currentRouteName, 'users.index_error', 'The current route name is correct');
assert.equal(Ember.Logger.error.callCount, 1, 'The error logger was called');
// Restore the Ember.Logger
Ember.Logger.error = emberLoggerError;
});
});
不过,事情可能会变得更加复杂。如果您的 visit 发生在 Promise 中(在我们的案例中确实如此,因为我们使用 ember-page-object 进行测试),那么您需要处理更多...
在RSVP 的单独循环中onerrorDefault 被触发,该循环调用Test.adapter.exception 和Ember.default.Logger.error(再次!)- 传递堆栈。因此,在这种情况下,您需要对 Test.adapter.exception 进行存根和监视 并且预计 Ember.default.Logger.error 会被调用两次!