typescript - Bruk avhengighetsinjeksjon med vue/vitest
- Min Oppsett
- Vue 3-applikasjon
- Pinia-butikker
- I min
main.ts:app.use(myPlugin) - I
MyPlugin.ts: Jeg oppretter og tilbyr betinget et repository (MyRepo) til applikasjonen basert på noen miljøforhold. Dette repositoryet kan enten interagere med en API eller gi falske data for utvikling og testing. - I
myStore.ts:
defineStore('myStore', () => {
const repo = inject<MyRepoInterface>('myRepo');
// ....
})
- Mitt problem
Jeg står overfor et problem når jeg skriver tester som avhenger av en store som selv avhenger av myStore. Når inject-funksjonen kalles innenfor testen min, får jeg følgende advarsel: [Vue warn]: inject() kan bare brukes inne i setup() eller funksjonelle komponenter. I tillegg er repo undefined, noe som resulterer i feil.
- Mitt spørsmål
Jeg leter etter en løsning for å kunne tilby repositoriet under oppsettet av testrammeverket mitt (Vitest). På denne måten kan jeg injisere det i koden min både under normal kjøring av applikasjonen og når jeg kjører tester. Hvordan kan jeg oppnå dette?
Enhver kritikk av måten jeg prøver å oppnå Dependency Injection på er velkommen. Takk!
Svar #1
Pinia-butikker er singletons som blir instantiert ved første kall av store-funksjonen. At inject brukes i Pinia-butikkenes setup-funksjon betyr at den første bruken bør være inne i Vue-komponentens setup eller samtidige livssyklushooks, mens det ikke er en slik begrensning for Pinia-butikker generelt.
Det ville også vært umulig å definere en butikk på denne måten med butikkalternativer i stedet for funksjon, selv om de vanligvis er utskiftbare.
En mer fleksibel og testvennlig måte er å bruke eksplisitt avhengighetsinjeksjon i lagringsmetoden:
let repo = ref(null as unknown as MyRepoInterface);
let init = (cfg: { repo: MyRepoInterface }) => {
repo.value = cfg.repo;
})
Og i App-komponenten:
useMyStore().init({
repo: inject<MyRepoInterface>('myRepo')
})
