typescript - Käytä riippuvuuksien injektiota vue/vitest kanssa


  1. Asetukseni
  • Vue 3 -sovellus
  • Pinia-tallit
  • Minun main.ts:ssäni: app.use(myPlugin)
  • Tiedostossa MyPlugin.ts: Luon ehdollisesti ja tarjoan sovellukselle repositorion (MyRepo) ympäristöolosuhteiden perusteella. Tämä repositorio voi joko olla vuorovaikutuksessa API:n kanssa tai tarjota väärennettyjä tietoja kehitystä ja testaus tarkoituksia varten.
  • Tiedostossa myStore.ts:
defineStore('myStore', () => {
  const repo = inject<MyRepoInterface>('myRepo');
  // ....
})
  1. Ongelmani

Minulla on ongelma testien kirjoittamisessa, jotka riippuvat kaupasta, joka puolestaan riippuu myStore:sta. Kun inject-funktiota kutsutaan testissäni, saan seuraavan varoituksen: [Vue warn]: inject() voidaan käyttää vain setup():n tai funktionaalisten komponenttien sisällä. Lisäksi repo on undefined, mikä johtaa virheisiin.

  1. Kysymykseni

Etsin ratkaisua tarjota arkisto testauskehykseni (Vitest) asetuksen aikana. Näin voin injektoida sen koodiini sekä normaalin sovelluksen ajon aikana että testejä ajettaessa. Kuinka voin saavuttaa tämän?


Kaikki kritiikki siitä, miten yritän saavuttaa riippuvuuksien injektoinnin, on tervetullutta. Kiitos!

Vastaus #1

Pinia-kaupat ovat singleton-olioita, jotka luodaan ensimmäisellä kutsulla store-funktiota. Se, että inject käytetään Pinia-kaupan asetustoiminnossa, tarkoittaa, että ensimmäisen käytön pitäisi olla Vue-komponentin setupissa tai nykyaikaisissa elinkaarikoukuissa, vaikka tällaista rajoitusta ei ole Pinia-kaupoille yleisesti.

Olisi myös mahdotonta määritellä myymälää tällä tavalla käyttämällä myymälävaihtoehtoja funktion sijaan, vaikka ne ovatkin yleensä vaihdettavissa.

Joustavampi ja testaajaystävällisempi tapa on käyttää eksplisiittistä riippuvuuksien injektiota store-metodissa:

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

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

Ja App-komponentissa:

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