title: How to mock Nuxt's useLazyFetch method with Vitest
body: <p>I'm trying to mock a call of Nuxt's <code>useLazyFetch()</code> method and let it respond with a .json fixture in a test. The stack I'm using is as follows:</p>
  <ul>
  <li>vitest 0.22.1</li>
  <li>@vue/test-utils 2.0.2</li>
  <li>Nuxt 3.0.0-rc.6</li>
  </ul>
  <p>Other answers to questions like this on Stackoverflow seem to be pointing at mocking Vue methods only but not Nuxt specific ones.
  The component using the tested <code>Comp.vue</code> one wraps it in a <code>&lt;Suspense&gt;</code> tag.</p>
  <p>The component under test looks like this:</p>
  <p><code>Comp.vue</code></p>
  <pre class="lang-html prettyprint-override"><code>&lt;script setup lang=&quot;ts&quot;&gt;
    // tried either of these imports for the test, or none using global components/composables
    //import { useLazyFetch } from '#app';
    //import { useLazyFetch } from '@/node_modules/nuxt/dist/app/composables/fetch';
  
    const {
      pending,
      error,
      data: myData,
    } = await useLazyFetch&lt;MyResponseType&gt;('https://some-url');
  &lt;/script&gt;
  
  &lt;template&gt;
    &lt;div&gt;
      &lt;div v-if=&quot;pending || error&quot;&gt;...&lt;/div&gt;
      &lt;div v-else-if=&quot;!pending &amp;&amp; !error &amp;&amp; myData&quot;&gt;
        &lt;Child
          v-for=&quot;data of myData&quot;
          &lt;...&gt;
        /&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  </code></pre>
  <p>Several different ways to solve it didn't lead to a solution. The raw test basically looks like this with a few setups shown in parallel:</p>
  <pre class="lang-js prettyprint-override"><code>import { describe, test, expect, vi } from 'vitest';
  import { mount, flushPromises } from '@vue/test-utils';
  import * as jsonResponse from './jsonResponse.test.json';
  
  describe('Comp', () =&gt; {
    const underTest = mount(Comp, {
      global: {
        mocks: {
           // 1st
           $fetch: {
            pending: false,
            error: undefined,
            myData: jsonResponse,
          },
          
          // 2nd
          useLazyFetch: new Promise((resolve) =&gt; {
            resolve(jsonResponse);
          }),
  
          // 3rd
          myData: jsonResponse,
          pending: false,
          error: undefined,
  
          // 4th
          useLazyFetch: vi.fn().mockImplementation(() =&gt;
            Promise.resolve({
              pending: false,
              error: undefined,
              myData: jsonResponse,
            })
          ),
  
          // 5th
          useLazyFetch: () =&gt; {
            Promise.resolve({
              pending: false,
              error: undefined,
              myData: jsonResponse,
            });
          },
        },
      },
    });
  
    test('test', async () =&gt; {
  
      // also tried these, based on other findings
      await new Promise((resolve) =&gt; setTimeout(resolve));
      await flushPromises();
  
      // should find 3 times Child component with .wrapper__entry belonging to Child
      const entries = underTest.findAll('.wrapper__entry');
      await expect(entries.length).toEqual(3);
    });
  });
  </code></pre>
  <p>Among tested options are:</p>
  <h2>Mock import</h2>
  <pre class="lang-js prettyprint-override"><code>vi.mock('@/node_modules/nuxt/dist/app/composables/fetch');
  const lazyFetch = await import('@/node_modules/nuxt/dist/app/composables/fetch');
  lazyFetch.useLazyFetch = vi.fn().mockResolvedValue(jsonResponse);
  </code></pre>
  <h2>vi.mock()</h2>
  <p>Using this import in <code>Comp.vue</code>: <code>import { useLazyFetch } from '#app';</code></p>
  <pre class="lang-js prettyprint-override"><code>vi.mock('app', () =&gt; ({
      useLazyFetch: Promise.resolve({
        pending: false,
        error: undefined,
        myData: jsonResponse,
      }),
    }));
  </code></pre>
  <h2>vi.spyOn()</h2>
  <pre class="lang-js prettyprint-override"><code>vi.spyOn(Comp, 'useLazyFetch').mockImplementation(() =&gt; {
      return Promise.resolve({
        pending: false,
        error: undefined,
        myData: jsonResponse,
      });
    });
  
  vi.spyOn(underTest.vm, 'useLazyFetch').mockResolvedValue({
     myData: jsonResponse,
  });
  </code></pre>
  <h2>vm.$options</h2>
  <pre class="lang-js prettyprint-override"><code>underTest.vm.$options.useLazyFetch = () =&gt; {
      return new Promise((resolve) =&gt; {
        resolve({
          pending: false,
          error: undefined,
          myData: jsonResponse,
        });
      });
    };
  </code></pre>
  <p>The output of <code>console.log(underTest.getCurrentComponent());</code> always shows</p>
  <pre class="lang-bash prettyprint-override"><code>...
  asyncDep: Promise {
      &lt;rejected&gt; ReferenceError: useLazyFetch is not defined
  ...
  </code></pre>
  <p>When not using <code>useLazyFetch()</code> but plain variables for <code>pending, error, myData</code> in <code>Comp.vue</code>, mocking like this is sufficient:</p>
  <pre class="lang-js prettyprint-override"><code>global: {
    mocks: {
      myData: jsonResponse,
      pending: false,
      error: undefined,
    }
  }
  </code></pre>
  <p>Does anyone have a hint how to solve this?</p>