Skip to content

mocking plugins used within nuxt #544

Open

Description

@gbyesiltas

Hey, firstly thank you for making this plugin, it looks very useful :)

Running this module seems to run the whole nuxt environment, including the plugins, and we have a plugin that makes a api call. We normally just mock the module where we import the api function but it doesn't seem to work in this case. For example:

// somePlugin.ts
import { fetchProducts } from "~/service/products";

export default defineNuxtPlugin(async () => {
    const products = fetchProducts();
    // do something with the products
});
// SomeComponent.nuxt.spec.js
import { describe, it, expect, vi } from "vitest";
import { shallowMount } from "@vue/test-utils";
import SomeComponent from "../SomeComponent.vue";

// trying to mock the products service so that the real api doesn't get called during the plugins
vi.mock("~/service/products");

describe("SomeComponent", async () => {
  it("Is a Vue instance", () => {
    const wrapper = shallowMount(SomeComponent);
    expect(wrapper.vm).toBeTruthy();
  });
});

I assume these mocks only work for the component that we are testing and not for the plugins in the nuxt environment for example. Do you have a suggestion about how to solve this?

Activity

  1. joel-wenzel commented on May 28, 2023

    @joel-wenzel
    Contributor

    I had a similar problem, my rest client is setup in a nuxt plugin and a subsequent plugin uses that client to make an app init api call.

    In my rest client plugin i have something like the following:

    const client = process.env?.TEST ? createMockClient() : createClient()
    provideClient(client)
    

    How you actually mock the requests is up to you

  2. gbyesiltas commented on May 30, 2023

    @gbyesiltas
    Author

    I had a similar problem, my rest client is setup in a nuxt plugin and a subsequent plugin uses that client to make an app init api call.

    In my rest client plugin i have something like the following:

    const client = process.env?.TEST ? createMockClient() : createClient()
    provideClient(client)
    

    How you actually mock the requests is up to you

    Thanks! Indeed we could do this but I personally like not having any test related logic in the actual code so I would definitely prefer somehow moving this to the vitest config or the test files themselves :/

  3. changed the title [-]How to mock modules used in plugins?[/-] [+]mocking plugins used within nuxt[/+] on Jun 2, 2023
  4. danielroe commented on Jun 2, 2023

    @danielroe
    Member

    it's worth noting that you can mock api routes with registerEndpoint: https://github.com/danielroe/nuxt-vitest#registerendpoint.

    There may be other reasons you would want to mock a plugin, and I think it should be possible, so leaving this issue up until we document it.

  5. Nicolas-Yazzoom commented on Aug 2, 2023

    @Nicolas-Yazzoom

    I'm using a plotting library in my project that is installed as a client side only plugin using the name convention (yourplugin.client.ts) since it uses browser API's. When running tests I get errors indicating the plugin is being executed in an environment that doesn't support it. Could it be that I need additional steps to get client side plugins to behave properly? Being able to mock this all together would be great since none of the things I want to test rely on this plugin. This is my code:

    // vitest.config.ts
    import { defineVitestConfig } from 'nuxt-vitest/config'
    
    export default defineVitestConfig({
      test: {
        environment: 'nuxt'
      }
    })
    // plugins/09.plotly.client.ts
    import Plotly from 'plotly.js-dist-min'
    
    export default defineNuxtPlugin(() => {
      return {
        provide: {
          Plotly
        }
      }
    })
  6. Austio commented on Oct 15, 2023

    @Austio

    @danielroe Would it be possible to have something that would allow us to replace a plugin in tests?

    Api would be akin to

    // In the test
    import { overridePlugin } from 'nuxt-vitest'
    
    it('allows me to do things that have great power', () => {
      overridePlugin('something', () => {
        ...function that would override the plugin and receive the same arguments
      })
    })
    
    
    
  7. danielroe commented on Nov 28, 2023

    @danielroe
    Member

    @adam-gipril Yes, we should build this in in future. (Adding setup files easily.) For now, you can likely implement with this hack:

    import { defineVitestConfig } from 'nuxt-vitest/config';
    
    export default defineVitestConfig({
      test: {
        environmentOptions: {
          nuxt: {
            overrides: {
              plugins: [
                // path to custom file
              ]
            }
          }
        }
      }
    });
  8. added
    staleIssue has not had recent activity or appears to be solved. Stale issues will be automatically closed
    on Apr 24, 2024
  9. removed
    staleIssue has not had recent activity or appears to be solved. Stale issues will be automatically closed
    on May 1, 2024
  10. Frallen commented on Jul 23, 2024

    @Frallen

    @Austio

    I found solution on YouTube

    In short, you need to mock all the elements
    image

  11. MikeBellika commented on Jun 12, 2025

    @MikeBellika
    Contributor

    Managed to get it working based on these docs: https://test-utils.vuejs.org/api/#global-mocks

    I have this plugin

    // plugins/hasFeature.ts
    export default defineNuxtPlugin(() => {
      const { hasFeature } = useAuth()
      return {
        provide: {
          hasFeature,
        },
      }
    })

    I then mock it like this:

    import { mountSuspended, mockComponent } from "@nuxt/test-utils/runtime"
    import { NavigationSettingsTabbed } from "#components"
    import { expect, it, vi } from "vitest"
    
    it("setting hidden with missing feature flag", async () => {
      const component = await mountSuspended(NavigationSettingsTabbed, {
        global: {
          mocks: {
            $hasFeature: vi.fn(() => false),
            $t: vi.fn((input) => input), // from nuxt-i18n. Returns the key directly
          },
        },
      })
      expect(component.find('[data-testid="settings-threat-link"]').exists()).toBe(
        false,
      )
    })

    Don't know if there are any downsides with this method but it works for me.
    Without it I get this error:

    TypeError: _ctx.$hasFeature is not a function
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions