Skip to content

Can't Mock $ref using Vue 3 on the Options API #2106

@ashewx

Description

@ashewx

Can't Mock $ref using Vue 3 on the Options API

I am using the Options API to build a component based off of a Vuetify component. The Vuetify component exposes a method called validate(). I am unable to mock the $refs for any Vue component using direct assignments. Code snippet below.

Steps to reproduce

Here is my component:

// Component.vue
<template>
  ...
  <v-text-field ref="start" v-model="startDateTime" />
  <v-text-field ref="end" v-model="endDateTime" />
  ...
</tempalate>

<script>
export default {
  methods: {
    runRefMethod() {
       this.$ref.start.validate();
       this.$ref.end.validate();
    }
  }
}
</script>

Then I try to make a unit test via Vitest:

// Component.spec.js
beforeEach(() => {
    wrapper = mount(Component, {
      shallow: true,
    });
});

it("test runRefMethod method", () => {
    wrapper.setData({ startSwitch: true, endSwitch: true });
    wrapper.vm.$refs = { // This will cause an error!!!
      start: {
        validate: vi.fn()
      },
      end: {
        validate: vi.fn()
      }
    };
    wrapper.vm.$refs.value.start.validate.mockReturnValueOnce(false);
    wrapper.vm.$refs.value.end.validate.mockReturnValueOnce(false);
    wrapper.vm.runRefMethod();
    expect(wrapper.vm.$refs.start).toHaveBeenCalled();
});

Expected behaviour

What should happen?
The expected behavor is that the $ref should be set on the component instance so that the method that is from the component can be executed. Is there a way to mock $ref in Vue 3? In Vue 2.x this was possible.

What happens instead?
The error returned would be.

'set' on proxy: trap returned falsish for property '$refs'

Possible Solution

So far I tried setting a mock or stub on mount but they do return the same error.

wrapper = mount(FilterPanel, {
      shallow: true,
      global: {
        plugins: [vuetify, pinia],
        stubs: {
          VTextField: {
            methods: {
              start: { validate: vi.fn() },
              end: { validate: vi.fn() }
            }
          }
        },
        mocks: {
          $refs: {
            value: {
              start: { validate: vi.fn() },
              end: { validate: vi.fn() }
            }
          } 
        },
      },
});

Is there a way to mock $ref in Vue 3? In Vue 2.x this was possible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions