3

I've built simple ErrorBoundary component for my project in Vue.js and I'm struggling to write unit test for it. Component's code below:

<template>
  <div class="overvue-error-boundary">
    <slot v-if="!error" />
    <div class="error-message" v-else>Something went horribly wrong here.</div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      error: false
    }
  },
  errorCaptured (error, vm, info) {
    this.error = true;
  }
}
</script>

I've created an ErrorThrowingComponent that throws an error on created() lifecycle hook so I can test ErrorBoundary:

const ErrorThrowingComponent = Vue.component('error-throwing-component', {
  created() {
    throw new Error(`Generic error`);
  },
  render (h) {
    return h('div', 'lorem ipsum')
  }
});

describe('when component in slot throws an error', () => {
  it('renders div.error-message', () => {
  // this is when error is when 'Generic error' is thrown by ErrorThrowingComponent
  const wrapper = shallowMount(OvervueErrorBoundary, {
    slots: {
      default: ErrorThrowingComponent
    }});
    // below code is not executed
    expect(wrapper.contains(ErrorThrowingComponent)).to.be.false;
    expect(wrapper.contains('div.error-message')).to.be.true;
  });
});

The problem is that ErrorThrowingComponent throws an error when I'm trying to actually mount it (thus failing entire test). Is there any way I can prevent this from happening?

EDIT: What I'm trying to achieve is to actually mount the ErrorThrowing component in a default slot of ErrorBoundary component to assert if ErrorBoundary will render error message and not the slot. This is way I created the ErrorThrowingComponent in the first place. But I cannot assert ErrorBoundary's behavior, because I get an error when trying to create a wraper.

8
  • what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??) Commented Nov 24, 2018 at 21:16
  • 1
    I've clarified this in the EDIT section above. Commented Nov 24, 2018 at 21:25
  • is the errorCaptured being invoked? can you try to add a log there and see if the issue reside in the capturer? Commented Nov 24, 2018 at 21:51
  • @Aviad, yes, the ErrorBoundary component has errorCaptured() hook that works. Component works as desired, I just cannot write unit test for it using vue-test-utils. Commented Nov 24, 2018 at 21:55
  • 1
    @Aviad, thanks for help, I've checked with people from Vue Land and they provided me a different approach that solves my problem. You can find it in my answer. Commented Nov 25, 2018 at 20:25

1 Answer 1

7

For anyone comming here with a similar problem: I've raised this on Vue Land's #vue-testing channel on Discord, and they suggested to move entire error-handling logic to a function which will be called from the errorCaptured() hook, and then just test this function. This approach seems sensible to me, so I decided to post it here.

Refactored ErrorBoundary component:

<template>
  <div class="error-boundary">
    <slot v-if="!error" />
    <div class="error-message" v-else>Something went horribly wrong here. Error: {{ error.message }}</div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      error: null
    }
  },
  methods: {
    interceptError(error) {
      this.error = error;
    }
  },
  errorCaptured (error, vm, info) {
    this.interceptError(error);
  }
}
</script>

Unit test using vue-test-utils:

describe('when interceptError method is called', () => {
  it('renders div.error-message', () => {
    const wrapper = shallowMount(OvervueErrorBoundary);
    wrapper.vm.interceptError(new Error('Generic error'));
    expect(wrapper.contains('div.error-message')).to.be.true;
  });
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.