How to catch errors in component/rendering test?

Version: ember@~3.1.0, ember-cli@~3.1.4

My component has a computed property that throws an error when the component is used without passing an attribute to replace the computed property.

How do I catch the error in my rendering test? Both assert.throws and assert.rejectsdo not catch the error.

My computed property looks like:

someProperty: computed(function() {
    throw new Error('some error');
})

My test looks like:

module('my-component test', function(hooks) {
    setupRenderingTest(hooks);

    test('throws', function(assert) {
        // Doesn't work, because render returns a promise.
        assert.throws(() => {
            render(hbs`{{my-component}}`);
        });

        // Doesn't work...
        assert.rejects(render(hbs`{{my-component}}`));
    ;})
});
2 Likes

This is a bug we are trying to get fixed. The work around is something like this:

module('my-component test', function(hooks) {
    setupRenderingTest(hooks);

    test('throws', function(assert) {
      Ember.onerror = function(error) {
        // make your error assertion here
      };
      await render(hbs`{{my-component}}`) 
    });
});

This is obviously not ideal, follow along here:

https://github.com/emberjs/ember-test-helpers/issues/310

3 Likes

I personally believe that the assert.rejects example you gave above is what we want. I just need to figure out how to properly entangle the rendering related error with the promise returned from render

Ember.onerror assertion throws if using your work-a-round:

Ember.onerror handler with invalid testing behavior detected. An Ember.onerror handler must rethrow exceptions when Ember.testing is true or the test suite is unreliable. See Add validation for Ember.onerror in testing. by rwjblue · Pull Request #304 · emberjs/ember-qunit · GitHub for more details.

Seems like Ember.onerror must be reset afterwards to avoid leaking between tests:

module('my-component test', function(hooks) {
  setupRenderingTest(hooks);

  let orgOnError;
  hooks.beforeEach(function() {
    orgOnError = Ember.onerror;
  });
  hooks.afterEach(function() {
    Ember.onerror = orgOnError;
  });

  test('throws', function(assert) {
    Ember.onerror = function(error) {
      // make your error assertion here
    };
    await render(hbs`{{my-component}}`) 
  });
});

FWIW, in order to avoid having to manually reset we created setupEmberOnerror which automatically resets after each test for you.

Checkout the docs here.

1 Like