1

I have this project structure:

/App.vue
|-components/CoponentA.vue
|-components/CoponentB.vue

In App.vue the ComponentB is not mounted until ComponentA emits an event:

<!-- App.vue -->
<template>
  <ComponentA @onMessage="onMessage"/>
  <ComponentB v-if="message"/>
</template>

<script setup lang="ts">
import { type Ref, ref } from 'vue';
import ComponentA from '@/components/ComponentA.vue';
import ComponentB from '@/components/ComponentB.vue';

const message: Ref<String | undefined> = ref();

const onMessage = (messageParam: String): void => {
  message.value = messageParam;
};
</script>

In my test I am trying to check this but I am not able to trigger a custom event on my test. The documentation says trigger is only for DOM events :/

My test code:

// App.spec.ts
import { describe, it, expect } from 'vitest'

import { shallowMount } from '@vue/test-utils'
import App from '@/App.vue'
import ComponentA from '@/components/ComponentA.vue'
import ComponentB from '@/components/ComponentB.vue'
import { nextTick } from 'vue'

describe('App', () => {
  it("renders the ComponentA component", (): void => {
    const wrapper = shallowMount<App>(App);
    expect(wrapper.findComponent(ComponentA).exists()).toBe(true);
  }); // -> works

  it("no renders the ComponentB component", (): void => {
    const wrapper = shallowMount<App>(App);
    expect(wrapper.findComponent(ComponentB).exists()).toBe(false);
  }); // -> works

  it('renders ComponentB when event emitted', async () => {
    const wrapper = shallowMount<App>(App);
    wrapper.findComponent(ComponentA).trigger('onMessage', 'MESSAGE');
    await nextTick();
    expect(wrapper.findComponent(ComponentB).exists()).toBe(true);
  }) // -> fails
})

Full components code:

<!-- Component A -->
<template>
  <h2>Component A</h2>
</template>

<script setup lang="ts">
import { onMounted } from 'vue';

const emit = defineEmits<{
  onMessage: [message: string]
}>();

onMounted(async () => {
  setTimeout(() => {
    emit("onMessage", "Loading finished!");
  }, 1000);
});
</script>

and:

<!-- Component B -->
<template>
  <h2>Component B</h2>
</template>

1 Answer 1

0

The only way to do this is using:

wrapper.vm.$emit()

In this case the working test will be like this:

it('renders ComponentB when event emitted', async () => {
  const wrapper = shallowMount<App>(App);
  const component = wrapper.findComponent(ComponentA);
  component.vm.$emit('onMessage', 'MESSAGE');
  await nextTick();
  expect(wrapper.findComponent(ComponentB).exists()).toBe(true);
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.