如何在 V-MENU 中测试 V-BTN?

Posted

技术标签:

【中文标题】如何在 V-MENU 中测试 V-BTN?【英文标题】:How to test V-BTN inside V-MENU? 【发布时间】:2021-08-20 01:59:38 【问题描述】:

我正在尝试为我的组件编写测试,在这个组件中我有一个<V-MENU>,当它被激活时,我会在该组件中得到一个表单,在这个表单中有一个<V-BTN>。所以我设法访问此菜单之外的按钮或项目,但是当我尝试在菜单内找到我的按钮时,测试将失败。

基本的 Vue 组件:

<v-btn
    data-testid="working-button"
    @click="workingbutton()"
    >
               Working Button
</v-btn>
<v-menu
    v-model="menu"
    data-testid="isMenu"
    :close-on-content-click="false"
    :nudge-
    offset-x
>
     <v-btn
         data-testid="btn-one"
         @click="doSomething"
        >
               BTN 1
    </v-btn>

    <v-card data-testid="card-test">
        <v-text-field
            v-model="country"
            outlined
            label="Email"/>

        <v-card-actions>
            <v-spacer></v-spacer>

            <v-btn
                data-testid="btn-two"
                @click="doSomething"
            >
                 login ? 'Login' : 'Register' 
            </v-btn>
        </v-card-actions>
    </v-card>
</v-menu>

测试单元:

const wrapper = mount(TestComponent, 
    store,
    localVue,
    vuetify
)

// Passed
expect(wrapper.vm.menu).toBe(false);
expect(wrapper.find('[data-testid="working-button"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="isMenu"]').exists()).toBe(true);
const menuButton = wrapper.find('[data-testid="working-button"]')
menuButton.vm.$emit('click')
expect(wrapper.vm.menu).toBe(true);

// Will Fail
expect(wrapper.find('[data-testid="btn-one"]').exists()).toBe(true);

// Will Fail
expect(wrapper.find('[data-testid="card-test"]').exists()).toBe(true);

// Will Fail
expect(wrapper.find('[data-testid="btn-two"]').exists()).toBe(true);

以上代码是一个基本示例,为了不浪费您阅读的时间,我试图将其缩短。 所以你可以在顶部看到我已经触发Working button 将菜单设置为真,然后试图找到按钮,我这样做的原因是,我认为菜单应该是真的,但它不是't,它仍然失败。

【问题讨论】:

【参考方案1】:

与大多数创建弹出窗口或叠加层的组件一样,Vuetify 的 v-menu 的内容不会在组件本身内呈现,而是在 its attach property 中指定的点处呈现,默认情况下是 Vue 应用的根目录。

您必须在 wrapper 之外查看渲染菜单。这应该可以做到,假设您从vue-test-utils 导入了createWrapper

const menu = createWrapper(document.body).find('.v-menu__content');

(更准确地说,您还可以传递作为您的应用程序根的特定元素,而不是 document.body。)然后您将在 menu 包装器上查找菜单中的所有内容wrapper 包装器。

【讨论】:

您好,感谢您的回答。我很抱歉,但我并不是真正的测试专家。所以正如你所说,我试图从vue-test-utils =&gt; like this =&gt; import mount, createLocalVue, DOMWrapper from '@vue/test-utils' 导入DOMWrapper,但它失败了这个错误`_testUtils.DOMWrapper is not a constructor`... @Atlas-Pio 哎呀,我一直在使用 vue-test-utils 2(用于 Vue 3)并放入它的 API。我已编辑我的答案以改用 v1 API。 好吧,我试过了,但又失败了。也许是因为我还在仙境。你能用我的例子来告诉我它是怎么做的吗?正如我所说,我可以在测试中找到 v-menu(在上面的示例中,v-menu 数据测试存在是正确的,但我无法访问 v-menu 中的按钮或元素/组件。 @Atlas-Pio 啊,抱歉,看起来 Vuetify 的结构与我见过的其他框架有点不同。我再次编辑了我的答案,以包含在应用程序根目录之外呈现的部分的正确选择器。这将在您的const menuButton = ... 行上方,然后将变为... = menu.find('[data-testid="working-button"]')

以上是关于如何在 V-MENU 中测试 V-BTN?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Vuetify v-menu 附加到可滚动列表中的父元素?

Vuetify 如何在 v-btn 中获取工作链接

v-menu 的 Vuetify 问题

如何使用 Vuetify 制作垂直 v-btn?

Vuetify <v-menu> 中的自动对焦和键盘导航

在 v-for 循环中使用 Vuetify v-btn 和加载器