3

Context

  • We are using Vue3 and Pinia and vitest
  • Rather than creating strict "unit" component tests, we're trying to do more E2E/integration testing (ie. where we're mounting and testing a component that then embeds other components and not mocking or stubbing them).

Issue

  • Since upgrading to Vue3, we seem to get this warning whenever a "child" component also uses the pinia store. The "child" components are using the same store as the "parent".
    • [Vue warn]: Property "$pinia" was accessed during render but is not defined on instance.

How do I make this warning go away? Is it a problem?

What I've looked into

  • I've checked that the child components can access the test pinia store correctly, and they can (ie. my tests can validate stuff about how the child has got things from the store). But the warning is noisy.
  • I can't see anything on the pinia docs that talk about how to manage this, and
  • I am not seeing other questions about this particular warning
  • On the Pinia website it says: When it comes to Pinia, you don't need to change anything for E2E tests, that's the whole point of these tests! You could maybe test HTTP requests, but that's way beyond the scope of this guide 😄.
  • I've looked into @vue/test-utils mocking and stubbing, but seeing as 'mount' is the bit that connects pinia to the app, I don't know if I can pass 'mounted' child components in the stubs section

This is an example of how I am mounting my components when I try to test them:

import { mount } from '@vue/test-utils'
import { createTestingPinia } from '@pinia/testing'

wrapper = mount(FilterDrawer, {
  plugins: [
    createTestingPinia({
       stubActions: false,
       initialState: {
         search: StateFactory.build()  // because store is named 'search'
        }
     })
  ]
})

FilterDrawer component uses mapStores to use the search store. It also has child components that use mapStores to use the search store.

7
  • Have you properly initialized pinia in your main.js file? You need to const pinia = createPinia(); app.use(pinia); Commented Jan 24, 2024 at 3:58
  • "we're mounting and testing a component" - this is integration test. As for e2e, you're supposed to have the same setup as you would for regular app, so you wouldn't have problems with setting up vue plugins, this is what the docs refer to Commented Jan 24, 2024 at 9:31
  • Thanks @Wesley, yes I am. Oh, that's interesting @EstusFlask, by the "same setup", do you mean for an E2E test I wouldn't use the createTestingPinia function at all, but would just bootstrap live pinia within a vitest test file (and then not be able to mock or stub or verify calls or anything)? Commented Jan 24, 2024 at 19:39
  • @EstusFlask, given it says "you don't need to change anything for E2E tests", that does sound to me like E2E tests should look very similar to unit tests (rather than they should look completely different and not use the testing framework). Commented Jan 24, 2024 at 19:46
  • @IsabelAnastasiadis E2e/integration are sometimes mixed and used as umbrella term, but e2e primarily means testing the whole thing, i.e. the app. You're using barebone vitest that isn't suitable for real e2e because it's not a real browser. For your case (integration) you need to explicitly make sure that you either provided vue plugins and other deps the comp relies on, or mock them, depending on the case. This is what the docs show pinia.vuejs.org/cookbook/testing.html#Unit-testing-components . You pasted it the wrong way and omitted "global" in mount(), probably the problem here Commented Jan 24, 2024 at 20:10

2 Answers 2

1

As shown in the documentation, mount accepts Vue plugins in global property, it should be:

wrapper = mount(FilterDrawer, {
  global: {
    plugins: [
      createTestingPinia({...})
    ]
  }
})
Sign up to request clarification or add additional context in comments.

Comments

1

You must create a pinia instance (the root store) and pass it to the app as a plugin:

import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

const pinia = createPinia();
const app = createApp(App);
app.use(pinia);

app.mount('#app');

Read the documentation here.

1 Comment

Thanks Mohesn. Yes I am doing that in my main.js file when the app is bootstrapped in code, and the app works fine normally. My tests are "component" tests, but I am also doing a similar thing as per the testing docs on pinia. I'll add an example to the main question so it's easier to read.

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.