[Vue warn]: Property "$pinia" was accessed during render but is not defined on instance

204 Views Asked by At

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.

2

There are 2 best solutions below

0
Estus Flask On BEST ANSWER

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

wrapper = mount(FilterDrawer, {
  global: {
    plugins: [
      createTestingPinia({...})
    ]
  }
})
1
Mohesn Mahmoudi On

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.