【问题标题】:Vue.js Testing - Banner not showing after button clickVue.js 测试 - 单击按钮后横幅未显示
【发布时间】:2020-08-19 20:32:20
【问题描述】:

我有一个 Vue.js 组件,它显示一个 BootstrapVue 横幅以响应提交错误。在手动测试期间一切正常,但相应的单元测试失败。

错误如下。

[vue-test-utils]: find did not return #submit-failure-banner, cannot call isVisible() on empty Wrapper

      36 | 
      37 |         const errorBanner = wrapper.find("#submit-failure-banner")
    > 38 |         expect(errorBanner.isVisible()).toBeTruthy()
         |                            ^
      39 |     })
      40 | })
      41 |
it("shows an error message on post failure", async () => {
    const wrapper = mount(NewSite, {
        localVue,
        provide: {
            sites: new Sites(internalServerErrorRequestHandler)
        }
    });
    const siteOwnerInput = wrapper.find('#new-site-owner-input');
    siteOwnerInput.setValue(owner);
    const saveButton = wrapper.find('#new-site-save');
    saveButton.trigger('click');
    await wrapper.vm.$nextTick();

    const errorBanner = wrapper.find("#submit-failure-banner")
    expect(errorBanner.isVisible()).toBeTruthy()
})

NewSite 组件的相关部分如下,从模板中的横幅元素开始。

<b-alert id="submit-failure-banner" variant="danger" v-model="banners.submitFailure" dismissible>
    {{ $t('$MESSAGE_SITE_SAVE_FAILED') }}
</b-alert>
export default class NewSite extends Vue {
    @Inject('sites') private sites!: Sites

    form = {
        owner: ''
    }
    banners = {
        submitFailure: false,
        ...
    }

    async postForm() {
        return await this.sites.create({
            owner: this.form.owner,
            state: SiteStatus.NEW
        }).save()
    }
   ...
   async onSave() {
        if (!this.checkForm()) {
            return;
        }
        try {
            await this.postForm();
            await this.$router.push({name: 'dashboard'})
        } catch (_) {
            this.banners.submitFailure = true;
        }
    }

Sites 类的相关部分只不过是使用请求处理程序的 POST 请求。这是生产中的axios,以及测试期间的模拟请求处理程序。 internalServerErrorRequestHandler 是这样定义的。

const internalServerErrorRequestHandler = {
    post(url: string, data: any): Promise<Response> {
        return Promise.reject()
    }
}

我通过console.log 声明验证了 html 不显示横幅。

【问题讨论】:

  • 我认为您需要在触发点击后添加一个额外的await wrapper.vm.$nextTick();,以便 Vue 有时间处理点击处理程序和&lt;transition&gt;(这是&lt;b-alert&gt; 的根)。
  • 我尝试添加一个额外的await wrapper.vm.$nextTick(); 并像here 描述的那样存根transition。都没有解决问题。
  • 其实你可能需要挂载选项attachToFocument: true,用documentQuerySelector('#submit-failure-banner')代替wrapper.find('#submit-failure-banner'),检查元素是div而不是isVisible。
  • 或者,在您的 await nextTick 之后,添加 await new Promise(resolve =&gt; requestAnimationFrame(resolve)),这将为触发未存根的转换留出时间。

标签: typescript vue.js bootstrap-vue vue-test-utils


【解决方案1】:

我通过存根BAlert 组件解决了问题,从而删除了transition 元素。我使用的存根如下。

<template>
    <div :v-show="value" :id="id">
        <slot/>
    </div>
</template>

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

    @Component
    export default class BAlertStub extends Vue {
        @Prop() value = false
        @Prop() id = ""
    }
</script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多