Spike
Spike

Reputation: 151

Vue 3 Vitest - Test v-model on input

I am trying to create a test for a BaseInput with a v-model prop. The expectation is the component will emit the changed input. When I update the input in the Vitest framework, there does not seem to be an emit triggered.

Component

<template>
  <label v-if="label">{{ label }}</label>
  <input
    v-bind="$attrs"
    :value="modelValue"
    :placeholder="label"
    @input="$emit('update:modelValue', $event.target.value)"
    class="field"
  />
</template>

<script>
export default {
  props: {
    label: {
      type: String,
      default: "",
    },
    modelValue: {
      type: [String, Number],
      default: "",
    },
  },
};
</script>

Test

import { describe, it, expect, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import BaseInput from "@/components/base/BaseInput.vue";

describe("BaseInput", () => {
  let wrapper

  beforeEach(() => {
    wrapper = mount(BaseInput, {
      propsData: {
        label: 'Test Label',
        modelValue: 'Test Value'
      }
    })
  })

  it('emits input value when changed', async () => {
    // Assert input value gets the new value
    await wrapper.find('input').setValue('New Test Value')
    expect(wrapper.find('input').element.value).toBe('New Test Value')

    // Assert input event is emitted
    await wrapper.vm.$nextTick()
    expect(wrapper.emitted().input).toBeTruthy() //this fails
  })

});

Result: there is nothing emitted from the input when the value is set.

How can the input be set to prove the component emits the new value of the input component?

Upvotes: 5

Views: 8730

Answers (1)

Spike
Spike

Reputation: 151

This is actually discussed as an example in the Vue Test Utils examples: https://test-utils.vuejs.org/guide/advanced/v-model.html#a-simple-example

Here is how you test v-model in Vue 3

import { describe, it, expect, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import BaseInput from "@/components/base/BaseInput.vue";

describe("BaseInput", () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(BaseInput, {
      propsData: {
        label: "Test Label",
        modelValue: "Test Value",
        "onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
      },
    });
  });

  it("emits input value when changed", async () => {
    // Assert input value gets the new value
    await wrapper.find("input").setValue("New Test Value");
    expect(wrapper.props("modelValue")).toBe("New Test Value");
  });
});

Upvotes: 3

Related Questions