ウェブサイト検索

TypeScript - Vue/Vitestで依存性注入を使用する


  1. 私の設定
  • Vue 3 アプリケーション
  • Piniaストア
  • 私の main.ts では:app.use(myPlugin)
  • MyPlugin.ts 内では、いくつかの環境条件に基づいてリポジトリ(MyRepo)を条件付きで作成し、アプリケーションに提供します。このリポジトリは、APIとやり取りするか、開発およびテスト目的で偽のデータを提供することができます。
  • myStore.ts で :
defineStore('myStore', () => {
  const repo = inject<MyRepoInterface>('myRepo');
  // ....
})
  1. 私の問題

私は、myStore に依存するストアに依存するテストを書くときに問題に直面しています。テスト内で inject 関数を呼び出すと、次の警告が表示されます: [Vue warn]: inject() は setup() または関数型コンポーネント内でのみ使用できます。 さらに、repo が undefined であるため、エラーが発生します。

  1. 私の質問

テストフレームワーク(Vitest)のセットアップ中にリポジトリを提供する方法を探しています。こうすることで、通常のアプリケーションの実行時にもテスト実行時にもコードに注入することができます。これをどのように実現できますか?


私が依存性注入を実現しようとしている方法に関する批判は大歓迎です。ありがとうございます!

回答 #1

Pinia ストアはシングルトンで、ストア関数の最初の呼び出し時にインスタンス化されます。Pinia ストアのセットアップ関数で inject が使用されるということは、最初の使用は Vue コンポーネントのセットアップ内または現代のライフサイクルフック内で行う必要があることを意味しますが、一般的な Pinia ストアにはそのような制限はありません。

一般的に相互に置き換え可能であるとしても、ストアを関数ではなくストアオプションでこのように定義することは不可能です。

より柔軟でテストに適した方法は、store メソッドで明示的な依存性注入を使用することです:

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

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

そして App コンポーネントでは:

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