typescript - Gunakan penyuntikan kebergantungan dengan vue/vitest


  1. Susunan Saya
  • Aplikasi Vue 3
  • Stor Pinia
  • Dalam main.ts saya: app.use(myPlugin)
  • Dalam MyPlugin.ts : Saya secara bersyarat membuat dan menyediakan sebuah repositori (MyRepo) kepada aplikasi berdasarkan beberapa syarat persekitaran. Repositori ini boleh berinteraksi dengan API atau menyediakan data palsu untuk tujuan pembangunan dan ujian.
  • Dalam myStore.ts :
defineStore('myStore', () => {
  const repo = inject<MyRepoInterface>('myRepo');
  // ....
})
  1. Masalah saya

Saya menghadapi masalah semasa menulis ujian yang bergantung pada store yang sendiri bergantung pada myStore. Apabila fungsi inject dipanggil dalam ujian saya, saya menerima amaran berikut: [Vue warn]: inject() hanya boleh digunakan di dalam setup() atau komponen fungsional. Selain itu, repo adalah undefined, menyebabkan ralat.

  1. Soalan saya

Saya sedang mencari penyelesaian untuk menyediakan repositori semasa penyediaan rangka kerja ujian saya (Vitest). Dengan cara ini, saya boleh menyuntiknya ke dalam kod saya sama ada semasa runtime aplikasi biasa dan semasa menjalankan ujian. Bagaimana saya boleh mencapainya?


Sebarang kritikan tentang cara saya cuba mencapai Penyuntikan Pergantungan dialu-alukan. Terima kasih !

Jawapan #1

Kedai Pinia adalah singleton yang dihasilkan pada panggilan pertama fungsi kedai. Bahawa inject digunakan dalam fungsi persediaan kedai Pinia bermaksud bahawa penggunaan pertama harus berada di dalam persediaan komponen Vue atau hooks kitaran hayat kontemporari, manakala tiada sekatan sedemikian untuk kedai Pinia secara umum.

Ia juga mustahil untuk mentakrifkan kedai dengan cara ini menggunakan pilihan kedai dan bukan fungsi, walaupun ia biasanya boleh ditukar ganti.

Cara yang lebih fleksibel dan mesra ujian ialah menggunakan suntikan kebergantungan secara eksplisit dalam kaedah simpan:

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

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

Dan dalam komponen App:

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