Vue.js unit testing ErrorBoundary












1















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.










share|improve this question

























  • what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

    – Aviad
    Nov 24 '18 at 21:16








  • 1





    I've clarified this in the EDIT section above.

    – rufus1530
    Nov 24 '18 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?

    – Aviad
    Nov 24 '18 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.

    – rufus1530
    Nov 24 '18 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.

    – rufus1530
    Nov 25 '18 at 20:25
















1















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.










share|improve this question

























  • what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

    – Aviad
    Nov 24 '18 at 21:16








  • 1





    I've clarified this in the EDIT section above.

    – rufus1530
    Nov 24 '18 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?

    – Aviad
    Nov 24 '18 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.

    – rufus1530
    Nov 24 '18 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.

    – rufus1530
    Nov 25 '18 at 20:25














1












1








1








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.










share|improve this question
















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.







unit-testing vue.js vuejs2 vue-test-utils






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 22:03







rufus1530

















asked Nov 24 '18 at 21:11









rufus1530rufus1530

411211




411211













  • what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

    – Aviad
    Nov 24 '18 at 21:16








  • 1





    I've clarified this in the EDIT section above.

    – rufus1530
    Nov 24 '18 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?

    – Aviad
    Nov 24 '18 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.

    – rufus1530
    Nov 24 '18 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.

    – rufus1530
    Nov 25 '18 at 20:25



















  • what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

    – Aviad
    Nov 24 '18 at 21:16








  • 1





    I've clarified this in the EDIT section above.

    – rufus1530
    Nov 24 '18 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?

    – Aviad
    Nov 24 '18 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.

    – rufus1530
    Nov 24 '18 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.

    – rufus1530
    Nov 25 '18 at 20:25

















what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

– Aviad
Nov 24 '18 at 21:16







what do you mean 'it throws an error when I mount it'? ...Theres an error being thrown on creation...(or am I missing something??)

– Aviad
Nov 24 '18 at 21:16






1




1





I've clarified this in the EDIT section above.

– rufus1530
Nov 24 '18 at 21:25





I've clarified this in the EDIT section above.

– rufus1530
Nov 24 '18 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?

– Aviad
Nov 24 '18 at 21:51





is the errorCaptured being invoked? can you try to add a log there and see if the issue reside in the capturer?

– Aviad
Nov 24 '18 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.

– rufus1530
Nov 24 '18 at 21:55





@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.

– rufus1530
Nov 24 '18 at 21:55




1




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.

– rufus1530
Nov 25 '18 at 20:25





@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.

– rufus1530
Nov 25 '18 at 20:25












1 Answer
1






active

oldest

votes


















2














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;
});
});





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462403%2fvue-js-unit-testing-errorboundary%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    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;
    });
    });





    share|improve this answer




























      2














      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;
      });
      });





      share|improve this answer


























        2












        2








        2







        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;
        });
        });





        share|improve this answer













        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;
        });
        });






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 20:22









        rufus1530rufus1530

        411211




        411211
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462403%2fvue-js-unit-testing-errorboundary%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Create new schema in PostgreSQL using DBeaver

            Deepest pit of an array with Javascript: test on Codility

            Fotorealismo