dimanche 12 août 2018

Run a test through vue-test-utils with a filled children object

I have been trying to test one line in my code with vue test utils for a week but I don't manage to get the line covered. I was wandering if it that is possible at all...

Some context:

THE CODE

It is about a list component of items components. In the list (Tabs) I'm setting my items (this.tabs) directly from the children components (Tab) in the template, just like following:

Tab.vue

<template>
    <div v-show='isActive'><slot></slot></div>
</template>

<script lang='ts'>
    import {Component, Prop, Vue} from 'vue-property-decorator';

    @Component({ name: "tab" })
    export default class Tab extends Vue {
        @Prop() public name: string;
        @Prop() public selected: boolean;

        public isActive: boolean = false;

        get href(): string {
            return '#' + this.name.toLowerCase().replace(/ /g, '-');
        }

        mounted() {
            this.isActive = this.selected;
        }
    }
</script>

<style scoped lang='scss'>

</style>

Tabs.vue

<template>
<div>
    <div class="tabs">
        <ul>
            <li v-for='tab in tabs' :class='{ "is-active": tab.isActive }'>
                <a :href='tab.href' @click='selectTab(tab)'></a>
            </li>
        </ul>
    </div>

    <div class="tabs-details">
        <slot></slot>
    </div>
</div>
</template>

<script lang='ts'>
    import {Component, Vue} from 'vue-property-decorator';

    @Component
    export default class Tabs extends Vue {
        public tabs: any[] = [];

        public selectTab(selectedTab): void {
            this.tabs.forEach(tab => {
                tab.isActive = (tab.name == selectedTab.name);
            });
        }

        public created() { 

          /************* HOW TO COVER THIS LINE? ********************/   
            this.tabs = this.$children as any[];
        }
    }
</script>

<style scoped lang='scss'>

</style>

THE PROBLEM

I would like to test that when I click some tab in the list with the command (in Tabs.vue) <a :href='tab.href' @click='selectTab(tab)'></a> the function selectetTab(tab) is toggling the variable isActive in the tab child and toggling the visibilty (in Tab.vue) <div v-show='isActive'><slot></slot></div>

MY APPROACH

Tabs.spec.ts

it('should only show the related tab content', () => {
    wrapper = mount(Tabs, {
        slots: {
            default: {
                render(h: any) {
                    return h(Tab, {}, 'Some Text')
                }
            }
        },
    });

    wrapper.setData({
        tabs: [
            {
                name: 'name',
                href: 'text',
                isActive: true,
            }
        ]
    });

    console.log(wrapper.html())
});

Until now, I have managed to set the slot's content in the child (Tab.vue) and the tabs in the list (Tabs.vue) as initial state, but what I want to achieve is that the initial state is empty and the tabs are being set through the children, since that is the expected behavior.

I also tried by mixing slots and stubs but I'm not able to do it

Aucun commentaire:

Enregistrer un commentaire