Leverage dependency injection with vue / vitest to enhance modularity and

  1. My Software Configuration
  • Developing a Vue 3 application
  • Utilizing Pinia stores
  • Initiating a plugin in my main.ts by using app.use(myPlugin)
  • Creating and providing a repository (MyRepo) in MyPlugin.ts based on specific environment conditions. This repository can interact with an API or provide dummy data for development and testing purposes.
  • In myStore.ts :
defineStore('myStore', () => {
  const repo = inject<MyRepoInterface>('myRepo');
  // ....
})
  1. Current Issue

Encountering an error while writing tests that rely on a store which in turn depends on myStore. When the inject function is invoked in my test, a warning message appears:

[Vue warn]: inject() can only be used within setup() or functional components.
Additionally, the repo remains undefined, leading to errors.

  1. Seeking Solution

On the lookout for a method to provide the repository during the setup of my testing framework (Vitest). By doing so, I aim to inject it into my code during regular application runtime as well as during test execution. Any suggestions on how I can accomplish this?


Open to feedback on my approach to Dependency Injection. Thank you for your input!

Answer №1

Pinia stores are instantiated as singletons upon the first call to the store function. The usage of inject within the Pinia store setup function requires the initial use to be within Vue component setup or similar lifecycle hooks, although this restriction does not apply to Pinia stores in general.

Creating a store using store options instead of a function would not be feasible using this method, even though these two approaches are typically interchangeable.

A more adaptable and test-friendly approach involves using explicit dependency injection in the store method:

let repo = ref(null as unknown as MyRepoInterface);

let init = (cfg: { repo: MyRepoInterface }) => {
  repo.value = cfg.repo;
})

Within the App component:

useMyStore().init({
  repo: inject<MyRepoInterface>('myRepo')
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating an array in TypeScript is a versatile and powerful feature that

While I have some familiarity with TypeScript, there is one thing that continues to intrigue me. I understand the distinction between Array<string> and string[]. I am aware that these declarations can be used interchangeably, such as: export class S ...

Piping in Angular 2 with injected dependencies

Is it possible to inject dependencies such as a service into Angular 2 pipes? import {Pipe, PipeTransform} from 'angular2/core'; import {MyService} from './service'; //How can I inject MyService into the pipe? @Pipe({name: 'expo ...

Is it possible to access the line number of a node using the TypeScript compiler API?

Is there a method to retrieve the line number of a node besides using node.pos? For example, something like node.lineNumber? ...

How to pass a single property as a prop in TypeScript when working with React

I have a main component with a parent-child relationship and I am looking for a way to pass only the product name property as props to my "Title" component. This way, I can avoid having to iterate through the information in my child component. To better i ...

Problem with TypeScript involving parameter destructuring and null coalescing

When using parameter destructuring with null coalescing in TypeScript, there seems to be an issue with the optional name attribute. I prefer not to modify the original code like this: const name = data?.resource?.name ?? [] just to appease TypeScript. How ...

Tips on streamlining two similar TypeScript interfaces with distinct key names

Presented here are two different formats for the same interface: a JSON format with keys separated by low dash, and a JavaScript camelCase format: JSON format: interface MyJsonInterface { key_one: string; key_two: number; } interface MyInterface { ...

"Optimize Your Data with PrimeNG's Table Filtering Feature

I'm currently working on implementing a filter table using PrimeNG, but I'm facing an issue with the JSON structure I receive, which has multiple nested levels. Here's an example: { "id": "123", "category": "nice", "place": { "ran ...

Utilizing v-for in Vue with TypeScript to generate multiple checkboxes

My goal was to capture the values of checkboxes and store them in an array using v-model. However, I encountered an issue where the first time I toggle a checkbox, it doesn't register. Only after checking a second box and hitting submit does the secon ...

What is the best way to create a case-insensitive sorting key in ag-grid?

While working with grids, I've noticed that the sorting is case-sensitive. Is there a way to change this behavior? Here's a snippet of my code: columnDefs = [ { headerName: 'Id', field: 'id', sort: 'asc', sortabl ...

Obtaining parameter types for functions from deeply nested types

I'm currently facing a challenge involving deeply nested parameters. When dealing with non-nested parameters, everything functions smoothly without any issues export type test = { 'fnc1': () => void, 'fnc2': () => void, ...

Do [(ngModel)] bindings strictly adhere to being strings?

Imagine a scenario where you have a radiobutton HTML element within an angular application, <div class="radio"> <label> <input type="radio" name="approvedeny" value="true" [(ngModel)]=_approvedOrDenied> Approve < ...

Why are all my Front-End requests being directed to the Back-End project?

Currently, I am learning about the integration of front-end and back-end interfaces. However, I have encountered a perplexing issue. The port for my back-end project is set to 8081. When I send a request to http://localhost:8081/hello, I receive a respons ...

Adjust the scroll position when the height of a div is modified

Imagine we have a large div A with a height value and below it are other divs B, C, and more. If the user is viewing divs B or C, and A reduces its height by half, the scrolling position will remain the same. However, divs B and C will move up by that amo ...

When calling a Vue.js method, it appears to be undefined

Currently, I'm working on developing a Chrome extension using Vue and Browserify. Within my component file, I'm attempting to invoke a method called animateBackground from the mounted hook. However, when checking the console, an error message is ...

Potential 'undefined' object detected in Vuex mutation using TypeScript

Currently, I am diving into learning Vue.js alongside Vuex and TypeScript. While working on my application, I encountered an error stating "Object is possibly 'undefined'" within the Vuex Store. The error specifically arises in the "newCard" mut ...

Incorporate matTooltip dynamically into text for targeted keywords

I'm currently tackling a challenge in my personal Angular project that utilizes Angular Material. I'm struggling to find a solution for the following issue: For instance, I have a lengthy text passage like this: When you take the Dodge action, ...

As I attempt to log in, the GitHub API is sending back a message stating that authentication

const fetchUser = async () =>{ let usernameValue : any = (document.getElementById('username') as HTMLInputElement).value; let passwordValue : any = (document.getElementById('password') as HTMLInputElement).value; const ...

Having difficulty replicating the sorting process in Vue.js for the second time

I need assistance with implementing sorting functionality in a Vue.js table component. Currently, the sorting mechanism is working fine on the first click of the th item, but it fails to sort the items on subsequent clicks. const columns = [{ name: &ap ...

At what point does a prop become officially designated as having the same value as what was initially passed to the component

I am experiencing unreliable behavior in my component, where a prop is passed and I need to debug it: <my-component :number="someNumber" /> The number prop is defined in my-component through a standard declaration: prop: ["number" ...

Mongoose encountered an error when attempting to cast the value "ObjectID" to an ObjectId at the specified path "red.s1"

My Mongoose schema is structured as follows: const gameSchema = new Schema({ matchNumber: { type: Number, required: [true, 'A match must have a number!'], unique: true }, red: { s1: { type: ...