Vue-test-utils: Vue Test Utils is not use modified template

Created on 9 Oct 2020  ·  2Comments  ·  Source: vuejs/vue-test-utils

Subject of the issue

So, after runing test and get the report, I changed the html template of component, but VueTestUtils library is still using the old version of template (before modification). It seems that VueTestUtils is caching the component, after mount.

Steps to reproduce

Versions

vue-jest: 3.0.7
@vue/test-utils: ^1.1.0,
vue-loader: ^15.9.2,
@vue/cli: 4.4.1

Component folder structure

 ---- Stepper
        |----> Index.vue
        |----> Stepper.js
        |----> Stepper.html
        |----> Stepper.css

Index.vue

  <template src="./Stepper.html"></template>
  <script src="./Stepper.js"></script>
  <style src="./Stepper.css"></style>
  <i18n src="./locales.json"></i18n>

Stepper.html

<div id="stepperBox" class="row">
    <div class="mt-5 col-12 text-center">
        <h4 class="font-weight-light">{{stepTitle}}</h4>
        <h5>a</h5>
    </div>
    <div class="col-12 offset-md-2 col-md-8 offset-xl-3 col-xl-6">
        <div class="d-none d-md-block">
            <ul class="stepsIndicators list-inline d-flex justify-content-center">
                <li v-for="(step, index) in stepsIcons" :key="index" class="list-inline-item">
                    <span class="stepIndicator" :class="getStepClass(index)">
                        <i class="stepIndicatorIcon" :class="getStepIcon(index)"></i>
                    </span>
                </li>
            </ul>
        </div>
        <div class="d-block d-md-none">
            <ul class="stepsIndicators list-inline d-flex justify-content-center">
                <li class="list-inline-item">
                    <span class="stepIndicator" :class="getStepClass(stepIndex)">
                        <i class="stepIndicatorIcon" :class="getStepIcon(stepIndex)"></i>
                    </span>
                </li>
            </ul>
        </div>
    </div>
</div>

Stepper.js

import vuexMixin from "@/mixins/vuex-mixins"

export default {
    name: "Stepper",
    mixins: [vuexMixin],
    data () {
        return {
            verifyIcons: ["fas fa-upload", "fas fa-check-circle"],
            signIcons: ["fas fa-upload", "fas fa-wrench", "fas fa-file-contract", "fas fa-clipboard-check"]
        };
    },
    computed: {
        userAction() {
            return this.action || "sign";
        },
        stepsIcons() {
            return this.userAction === "sign" ? this.signIcons : this.verifyIcons;
        },
        stepTitle(){
            return this.$t(this.userAction)[this.stepIndex];
        }
    },
    created() {
        const userAction = this.$route.path.includes("sign") ? "sign" : "verify";
        this.setCurrentAction(userAction);
    },
    methods: {
        getStepClass (index) {
            return this.stepIndex === index ? "active" : "passive";
        },
        getStepIcon (index) {
            return this.stepIndex > index ? "fas fa-check" : this.stepsIcons[index];
        },
    }
};

Stepper.css

...Too much css

The test file code

import Vuex from "vuex";
import i18n from "@/i18n";
import router from "@/router.js";
import { cloneDeep } from "lodash";
import stepperStore from "@/store/modules/stepper.js"
import { createLocalVue, mount } from "@vue/test-utils";
import Stepper from "@/components/Stepper/Index.vue";

describe("Stepper.vue", () => {

    // Pre config
    let store;
    const localVue = createLocalVue();
    localVue.use(Vuex);
    beforeEach(async () => {
        store = new Vuex.Store(cloneDeep(stepperStore))
    });

    // Stepper store testing 
    test(`Testing store step increment && decrement`, () => {
        expect(store.state.stepIndex).toBe(0);
        store.commit("INCREMENT");
        expect(store.state.stepIndex).toBe(1);
        store.commit("DECREMENT");
        expect(store.state.stepIndex).toBe(0);
    });

    test(`Testing store step set && reset`, () => {
        expect(store.state.stepIndex).toBe(0);
        store.commit("SET", 1);
        expect(store.state.stepIndex).toBe(1);
        store.commit("RESET");
        expect(store.state.stepIndex).toBe(0);
    });

    // Stepper UI interaction testing 
    it(`Testing UI interaction on step change`, async () => {
        const wrapper = await mount(Stepper, { store, router, i18n, localVue });
        expect(wrapper.html()).toContain("<h5>a</h5>");        
    });
});

The test result

FAIL  tests/unit/stepper.spec.js
Stepper.vue
    √ Testing store step increment && decrement (11ms)
    √ Testing store step set && reset (8ms)
    × Testing UI interaction on step change (60ms)

● Stepper.vue › Testing UI interaction on step change

    expect(received).toContain(expected) // indexOf

    Expected substring: "<h5>a</h5>"
    Received string:    "<div id=\"stepperBox\" class=\"row\">
    <div class=\"mt-5 col-12 text-center\">
        <h4 class=\"font-weight-light\"></h4>
        <h3>s</h3>
    </div>
    <div class=\"col-12 offset-md-2 col-md-8 offset-xl-3 col-xl-6\">
        <div class=\"d-none d-md-block\">
        <ul class=\"stepsIndicators list-inline d-flex justify-content-center\">
            <li class=\"list-inline-item\"><span class=\"stepIndicator passive\"><i class=\"stepIndicatorIcon fas fa-upload\"></i></span></li>
            <li class=\"list-inline-item\"><span class=\"stepIndicator passive\"><i class=\"stepIndicatorIcon fas fa-wrench\"></i></span></li>
            <li class=\"list-inline-item\"><span class=\"stepIndicator passive\"><i class=\"stepIndicatorIcon fas fa-file-contract\"></i></span></li>
            <li class=\"list-inline-item\"><span class=\"stepIndicator passive\"><i class=\"stepIndicatorIcon fas fa-clipboard-check\"></i></span></li>
        </ul>
        </div>
        <div class=\"d-block d-md-none\">
        <ul class=\"stepsIndicators list-inline d-flex justify-content-center\">
            <li class=\"list-inline-item\"><span class=\"stepIndicator active\"><i class=\"stepIndicatorIcon\"></i></span></li>
        </ul>
        </div>
    </div>
    <notifications group=\"errorMessageDOMLocation\" position=\"bottom right\"></notifications>
    </div>"

    37 |     it(`Testing UI interaction on step change`, async () => {
    38 |         const wrapper = await mount(Stepper, { store, router, i18n, localVue });
    > 39 |         expect(wrapper.html()).toContain("<h5>a</h5>");        
        |                                ^
    40 |     });
    41 | });

Expected behaviour

After changing the html code, and running test over tested component, the new html code should be used.

Actual behaviour

VueTestUtils is still use the old version of component template, even if I remove more than half of html code.

Possible Solution

Not sure. I tried to use wrapper.destroy(), but it doesn't help.

Most helpful comment

Are you using Jest? Try running yarn jest --no-cache (or yarn test:unit --no-cache for Vue CLI).

I really don't think this is an issue with VTU, sounds like a caching problem.

All 2 comments

Are you using Jest? Try running yarn jest --no-cache (or yarn test:unit --no-cache for Vue CLI).

I really don't think this is an issue with VTU, sounds like a caching problem.

Thanks, it works very well now .

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vilarinholeo picture vilarinholeo  ·  3Comments

38elements picture 38elements  ·  3Comments

dlumbrer picture dlumbrer  ·  3Comments

AustinGil picture AustinGil  ·  3Comments

lusarz picture lusarz  ·  3Comments