我尝试测试我的自定义输入组件。但我不知道如何正确地做到这一点,因为我没有找到任何如何测试它的信息。 我唯一发现的是来自这个Mocking Form and Field Contexts
我的自定义组件:
<script setup>
import { useField } from 'vee-validate';
import { watch, toRef } from 'vue';
const props = defineProps({
modelValue: {
type: undefined,
default: undefined,
},
type: {
type: String,
default: 'text',
},
label: {
type: String,
default: '',
},
name: {
type: String,
required: true,
},
});
const emit = defineEmits(['update:modelValue']);
const { value, setValue, errorMessage } = useField(toRef(props, 'name'));
watch(
() => value.value,
(newValue) => {
emit('update:modelValue', newValue);
}
);
watch(
() => props.modelValue,
(newValue) => {
setValue(newValue);
}
);
</script>
<template>
<div class="form-group">
<label v-if="props.label" :for="props.label">{{ props.label }}</label>
<input
:id="props.label"
v-model="value"
:name="props.name"
:type="props.type"
class="form-input"
/>
<span v-if="errorMessage" class="form-error" role="alert">{{ errorMessage }}</span>
</div>
</template>
我的测试文件:
import { render, screen, waitFor } from '@testing-library/vue';
import AppField from './AppField.vue';
import { FormContextKey, useForm } from 'vee-validate';
import userEvent from '@testing-library/user-event';
const rednerField = ({ label, type, ...rest } = {}) => {
const options = { props: { name: 'inputName', label, type }, ...rest };
render(AppField, options);
};
const user = userEvent.setup();
const MockedForm = useForm({
validationSchema: {
inputName(value) {
if (value && value.trim()) {
return true;
}
return 'This is required';
},
},
});
describe('showing error', () => {
it('show error if field is invalid', async () => {
rednerField({ label: 'labelName', global: { provide: { [FormContextKey]: MockedForm } } });
const input = screen.getByLabelText('labelName');
user.type(input, ' ');
await waitFor(() => {
expect(screen.getByRole('alert')).toHaveTextContent('This is required');
});
});
});
请告诉我这个测试是否正确编写,我怎样才能摆脱警告,或者这是正常的吗?
我自己才知道如何做到这一点。这个问题可能已经有 2 年历史了,但是 vee-validate 文档并没有真正解释如何处理这些问题,因此这可能会帮助下一个遇到这个问题的人。
我最终创建了一个扩展组件
setup()
的辅助函数,因此 provide
中的 useForm
将在正确的上下文中运行。我讨厌像这样连接到库,但如果没有它,我就无法获得模拟表单上下文。
通过此设置,您应该能够针对任何预期进行工作测试
validationSchema
export function getExtendedComponent(
inputComponent: ReturnType<typeof defineComponent>,
options: { mockFormData: FormData }
): Component {
return {
...inputComponent,
setup(props, ctx) {
let result = {};
if (options.mockFormData) {
const useFormResult = useForm(options.mockFormData);
/** @ts-ignore non-problematic type differences */
provide(FormContextKey, useFormResult);
}
if (inputComponent.setup) {
const setupResult = inputComponent.setup(props, ctx);
result = { ...result, ...setupResult };
}
return result;
},
};
}
const mockFormData = {
validationSchema: {
username(value: string) {
if (value && value.trim()) {
return true;
}
return "required";
},
},
};
const InputComponentWrapped: Component = getExtendedComponent(InputComponent, {
mockFormData,
});