0

I can't access functions of the wrapper.vm in the unit tests once my component become async on the top-level (needed to use <suspense> feature).

<script setup lang="ts">
const state = reactive({ text: '' });

// -------
// How it was before
const addition = '3';  // <-- This works 

// This is what I want!!!!!
const addition = await Promise.resolve('3'); // <-- This "await" doesn't let me access `wrapper.vm.getText()` in unit tests (undefined)
// -------

function getText(): string {
  return '12' + addition;
}

</script>

<template>
  <section class="foo">
    <button @click="getText()">{{ state.text }}</button>
  </section>
</template>

This is how I'm trying to test getText():

describe('some', () => {
  describe('getText', () => {
    it('should return "123"', async () => {
      const wrapper = mount(Some);
      await flushPromises();
      const result = wrapper.vm.getText(); // <--- "getText()" is udnefined!!! 
      expect(result).toBe('123');
    });
  });
});

So, how to access getText() in unit-tests? I use vitest btw.

I know some solutions to test the html, but they aren't letting me to access functions either.

For sure I can test via "click". But what if I need to mock a function?

eXception
  • 1,307
  • 1
  • 7
  • 22

3 Answers3

1

For anyone who is looking for workaround

P.S. You might be needed to right configure your plugins and mocks

import { mount, flushPromises } from '@vue/test-utils';
import { describe, expect, it } from 'vitest';
import { defineComponent } from 'vue';
import YourAsyncSetupComponent from '/path/to/your/component';

// Create suspense wrapper for your component
const SuspenseWrapperComponent = defineComponent({
  components: { YourAsyncSetupComponent },
  template: `
    <Suspense>
      <YourAsyncSetupComponent />
    </Suspense>
  `,
});

const createExchangeViewComponent = () => {
  const wrapper = mount(SuspenseWrapperComponent, {
    global: {
      plugins: [
        // set up plugins
      ],
    },
  });

  return wrapper;
};

describe('YourAsyncSetupComponent.vue', () => {
  ///
  ///
  ///
  it('Component renders', async () => {
    // Create and mount suspense wrapper component
    const suspenseWrapper = createExchangeViewComponent();
    // Wait suspense promise
    await flushPromises();

    // Access your target component
    const wrapper = suspenseWrapper.findComponent({ name: 'YourAsyncSetupComponent' });

    // Continue your tests
    expect(wrapper.text()).contains('Your text');

    suspenseWrapper.unmount();
  });
});
0

I read the code and (I think) didn't get the point :/

Ideas:

  • refactor:
const getText = async (): Promise<string> => {
  const addition = await Promise.resolve('3');
  return `12${addition}`;
};
  • in the test: await wrapper.vm.getText()

Hope that helps!

benjaroa
  • 334
  • 2
  • 8
  • This what I'd do, but in order to use feature of vue 3, `await Promise.resolve('3');` should be on the top level of the component, not inside the function. Cause for "suspense" we should have so called "async setup". – eXception Oct 26 '22 at 07:08
0

@eXception, Apologize for the late response, your question is quite incomplete though, we usually mention the dev stack like:

  • plugins used like router or store, etc...
  • testing framework

However, I believe;

  • the problem: you just need to access method on wrapper from the test. that said, so depending on your stack you have to await on some process, anyhow
await nextTick(); // is mostly the answer

await router.isReady(); // if you use router

try to check issues/1770#issuecomment-1245751892

Cheers

Ahmed Shehab
  • 1,657
  • 15
  • 24
  • Thanks for the answer, however I don't think that's the solution, since `await nextTick();` does more or less as `await flushPromises();`. The issue here as I understand is that with component you got a wrapper of an external component, you and your "real" component is a "child" which doesn't expose methods. Also I'm pretty sure this happens with any testing frameworks, cause it's how Vue works, so no need to mention. Besides, they are listed in tags – eXception Nov 25 '22 at 11:59