VeeValidate4。如何测试使用useField的自定义字段组件?

问题描述 投票:0回答:1

我尝试测试我的自定义输入组件。但我不知道如何正确地做到这一点,因为我没有找到任何如何测试它的信息。 我唯一发现的是来自这个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');
    });
  });
});

此测试工作正常,但控制台有警告: console log from jest

请告诉我这个测试是否正确编写,我怎样才能摆脱警告,或者这是正常的吗?

javascript vue.js jestjs vee-validate vue-testing-library
1个回答
0
投票

我自己才知道如何做到这一点。这个问题可能已经有 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,
});
© www.soinside.com 2019 - 2024. All rights reserved.