Sho*_*zer 2 vue-test-utils vuejs3 vitest
我正在尝试模拟<select>在 Vitest 测试中的元素中选择一个选项。<select>模拟选择应设置绑定到s的 ref 的值v-model。正如您在下面看到的,我根据此处和互联网上其他地方的其他问题尝试了许多不同的方法,但我就是无法使其在我的情况下发挥作用。
我正在使用以下内容:
我创建了一个非常基本的 Vue 组件,其中包括标题和元素<select>:
<script setup lang="ts">
import { ref } from "vue";
const items = ["item 1", "item 2", "item 3", "item 4", "item 5"];
const selectedItem = ref<string>("");
// this is a placeholder for a more complex function
async function handleSubmit(): Promise<void> {
console.log("in handleSubmit()");
console.log(quotedString(selectedItem.value));
}
// this is just here for a prettier output
function quotedString(s: string): string {
return s === undefined ? s : '"' + s + '"';
}
</script>
<template>
<h1>Foo</h1>
<p>
<select v-model="selectedItem">
<option disabled value="">Please Select</option>
<option v-for="item in items" :value="item" :key="item">
{{ item }}
</option>
</select>
</p>
<p>Selected {{ selectedItem }}</p>
<p><button @click="handleSubmit">Submit</button></p>
</template>
Run Code Online (Sandbox Code Playgroud)
是<select>绑定的selectedItem,当我在浏览器中打开该代码时,一切正常,这意味着选择一个元素后,该元素的名称将显示在页面上,单击提交按钮后,该元素的名称将写入控制台。
但是,当我尝试以下测试代码时,该语句console.log(quotedString(selectedItem.value));会生成未定义或空字符串,这意味着模拟选择不起作用。这是测试代码,包括几种不同的尝试。
import { describe, test } from "vitest";
import { shallowMount, VueWrapper } from "@vue/test-utils";
import FooView from "./FooView.vue";
describe("FooView", (): void => {
test("can simulate select selection", async (): Promise<void> => {
const fooViewWrapper = shallowMount(FooView);
const selectFieldWrapper = fooViewWrapper.find("select");
const options = selectFieldWrapper.findAll("option");
// ATTEMP 0
// This is the preferred way according to https://v1.test-utils.vuejs.org/api/wrapper/setvalue.html but still does not work
// await selectFieldWrapper.setValue("item 2");
// expect(selectFieldWrapper.element.value).toBe("item 2");
// alternatively
// selectFieldWrapper.element.value = "item 2";
// selectFieldWrapper.trigger('change')
// expect(selectFieldWrapper.element.value).toBe("item 2");
// ATTEMPT 1
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// await options.at(2)!.trigger("click");
// --> output: empty string
// ATTEMPT 2
// await options.at(2)?.setSelected(); // setSelected() is private :(
// --> output: empty string
// ATTEMPT 3
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// options.at(2)!.element.selected = true;
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// await options.at(2)!.trigger("input");
// --> output: empty string
// ATTEMPT 4
// await selectFieldWrapper.setValue("item 2");
// await selectFieldWrapper.trigger("change");
// --> output: undefined
// ATTEMPT 5
// await selectFieldWrapper.setValue("item 2");
// await selectFieldWrapper.trigger("input");
// --> output: undefined
// ATTEMPT 6
// await selectFieldWrapper.setValue("item 2");
// await selectFieldWrapper.trigger("click");
// --> output: undefined
// ATTEMPT 7
// selectFieldWrapper.element.selectedIndex = 2;
// await selectFieldWrapper.trigger("change");
// --> output: undefined
// ATTEMPT 8
// selectFieldWrapper.element.selectedIndex = 2;
// await selectFieldWrapper.trigger("input");
// --> output: empty string
// ATTEMPT 9
// selectFieldWrapper.element.selectedIndex = 2;
// await selectFieldWrapper.trigger("click");
// --> output: empty string
// ATTEMPT 10
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// await options.at(2)!.trigger("click");
// --> output: empty string
// ATTEMPT 10
// await selectFieldWrapper.trigger("click");
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// await options.at(2)!.trigger("click");
// await selectFieldWrapper.trigger("input");
// --> output: empty string
// ATTEMPT 11
// selectFieldWrapper.element.click();
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// options.at(2)!.element.click();
// await nextTick();
// --> output: empty string
// ATTEMPT 12
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// options.at(1)!.trigger('click');
// await nextTick();
// --> output: empty string
// ATTEMPT 13
// await selectFieldWrapper.setValue(2);
// await selectFieldWrapper.trigger("click");
// --> output: undefined
// ATTEMPT 14
// await selectFieldWrapper.setValue(2);
// await selectFieldWrapper.trigger("change");
// --> output: undefined
// selectFieldWrapper.element.selectedIndex = 2;
// await selectFieldWrapper.trigger("input");
// console.log(options.at(2)?.element.selected);
// console.log(selectFieldWrapper.element.selectedIndex);
await clickSubmitButton(fooViewWrapper);
});
});
async function clickSubmitButton(fooViewWrapper: VueWrapper): Promise<void> {
const submitButtonWrapper = fooViewWrapper.find("button");
submitButtonWrapper.element.click();
}
Run Code Online (Sandbox Code Playgroud)
我发现有趣的是我可以像这样设置所选选项:
options.at(2)!.element.selected = true;
console.log(options.at(2)?.element.selected); // prints *true*
Run Code Online (Sandbox Code Playgroud)
但即使这样我也没有得到想要的输出。
回答我自己的问题:问题不在于测试本身,而在于 vitest 配置。我使用 happy-dom 作为它的环境,这显然在这种特殊情况下不起作用。将环境切换到jsdom就是解决方案。这样我的尝试 0 就成功了,所以这是有效的:
await selectFieldWrapper.setValue("item 2");
expect(selectFieldWrapper.element.value).toBe("item 2");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3044 次 |
| 最近记录: |