質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

2778閲覧

WPF PrismでコンストラクタにIRegionManagerを指定するViewModelをxUnitでテストしたい

ttact

総合スコア170

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2021/12/14 00:29

編集2021/12/14 01:33

■環境
Windows 10 Pro 21H2 64bit 日本語版 build 19044.1387
Visual Studio Professional 2019 日本語版 ver.16.11.7
Prism Template Pack 2.3.0
.NET 5.0
Prism.Core 8.1.97

■質問の概要
PrismでViewModelのユニットテストを行う際に参考になるwebサイトや書籍があったらご紹介頂きたく思います。

■課題
WPF/Prism/MVVM/DIを一度に学習しはじめて、わけわからないことになってます...
そのうちの1つについて質問したく思います。

Prismのサンプルコードにある

C#

1public HogeViewModel(IRegionManager regionManager) 2{ 3 _regionManager = regionManager; 4 5 MyCommand = new DelegateCommand(() => 6 { 7 _regionManager.RequestNavigate("ContentRegion", nameof(FooView)); 8 }); 9}

みたいなViewModelについて、xUnitでユニットテストしようと思っています。

「Prism IRegionManager for test implementation」で検索をかけたところ、例えば以下のようなページが見つかりました。
https://github.com/PrismLibrary/Prism/issues/65
しかし本issueはクローズされており、中に出てくるMockRegionManagerで検索をかけても、実際にViewModelのコンストラクタに渡すインスタンスを生成しているコードが見つかりませんでした。

「IRegionManager Mock」で検索をかけたところ、以下のようなページが見つかりました。
https://stackoverflow.com/questions/62445269/unable-to-mock-regionmanager-activeviews-first
これを見るに、Moqというライブラリを使って必要なインターフェースを実体化すれば良さそうに思えます。しかし今度は見慣れない「IViewsCollection」というものが出てきました。こちらはdocs.microsoft.comにドキュメントページがありましたが、記述がほぼ何もない状態で、ユニットテストにとって何のために必要なのか、上記StackOverflowで示されるコードが自身のユニットテストにとって過不足ないのかどうかがよくわかりませんでした。

PrismにおけるViewModelのユニットテストについて、網羅的に扱っているwebサイトや電子書籍はないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ry188472

2021/12/14 04:47

間違っていたらすみません。IRegionManagerをDIしたい理由は画面遷移のためでしょうか?
ttact

2021/12/14 04:52

はい。Prismのサンプルコードで見た感じで、IRegionManagerはページ(ウィンドウの一部)を別のUserControlに切り替えるためのもの、と理解しております。
TN8001

2021/12/14 09:27

テンプレートの「Prism Full App」で作ると、 FullApp1.Modules.ModuleName.Tests.ViewModelsアセンブリ(Testsフォルダの中)に、 _regionManagerMock = new Mock<IRegionManager>(); や var vm = new ViewAViewModel(_regionManagerMock.Object, _messageServiceMock.Object); のようなコードが作られますが、そういう話ですか?
ttact

2021/12/15 02:13

>TN8001さん IRegionManagerについては、まさにこれです!...公式のテンプレートでもMoqを使っているんですね。 IViewsCollectionの件や網羅的な内容の紹介については引き続き募集しますので、まだクローズしません。
guest

回答2

0

自己解決

ry188472さん、TN8001さん、コメントとご回答をありがとうございます。大変参考になりました。

私が今扱っているシステムでは、やはり画面遷移をテストしたい、かつ現下のビューを表示しているリージョンとは異なるリージョンに対する指示を確認したい、ということがわかりました。
そのためやはりIRegionManagerは欲しいということで、お二方に頂いた情報を元に、以下のようにテストを組みました。

(1)
xUnitプロジェクトを作成。Nugetパッケージとして以下を追加:

  • Prism.Core
  • Moq

(2)
以下のようにテストを記述。NextCommandはMainWindowViewModel.RegionNameで識別されるリージョンにView2を表示するはずのコマンドです。

C#

1public void Test1() 2{ 3 var regionManagerMock = new Mock<IRegionManager>(); 4 var vm = new View1ViewModel(regionManager.Object); 5 vm.NextCommand.Execute(null); 6 regionManagerMock.Verify(r => r.RequestNavigate(MainWindowViewModel.RegionName, nameof(View2)), Times.Once); 7}

ただしこれですと、IConfirmNavigationRequest.ConfirmNavigationRequest()にて遷移をキャンセルした際に実際にリージョンに設定されているビューが確認できません。それは今後の課題ということで、PrismやMoqの詳細を調べて解決しようと思います。

投稿2021/12/16 10:27

ttact

総合スコア170

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttact

2021/12/16 10:27

IViewsCollectionについてはどうしてもわからないので、一旦諦めました。。。
guest

0

期待された回答ではないかもしれませんが、Prismを使って画面遷移する場合、VMはINavigationAwareインターフェイスを実装し、画面遷移後にOnNavigatedToメソッドでIRegionNavigationServiceの実体をnavigationContext.NavigationServiceから取得する方法をおすすめします。

https://qiita.com/kwhrkzk/items/719354e86a15ccac7296
https://webbibouroku.com/Blog/Article/prism-navigation#outline__3
https://elf-mission.net/programming/wpf/episode07/

この方法ですとINavigationAwareはコンストラクタインジェクションする必要がありませんので、テスト時に困ることはありません(ただしINavigationAwareのセットはコンストラクタ後になるため、.NET5以降でNullable=enable設定の場合は初期値をnull!にしないと警告が出る)。

また、私は画面遷移そのものはテストしません。それはPrismの責務のためです。画面遷移関係でテスト実装するのは「画面遷移のきっかけになるボタン押し等イベントのテスト(イベント発生可否等)」「画面遷移先の決定処理」「渡すデータの生成ロジック」「遷移先画面のデータ受領処理」にしています。これらがOKならPrismによる画面遷移自体は成功するためです。ただこれらはprivate/protectedメソッドになっていることがあるのでChainingAssersion等で無理やりテストしており、もっとよい方法があるのかもしれません。

投稿2021/12/14 05:05

ry188472

総合スコア74

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttact

2021/12/14 06:21

Prismでの画面遷移全般について、非常に参考になるページをご紹介頂きありがとうございます! このコメントを書いている段階では、まだ直接的な回答を募集しておりますのでベストアンサーにはしませんが、2番目のURLの記事にある内容が別の悩み事だった「ViewModelにViewのクラス名を記述する」という事柄に対する回避策を示して下さっているので、とても助かりました。
ttact

2021/12/14 06:28

なお画面遷移のテストの件ですが、ユーザーとダイアログで対話しつつ一連の処理を流すシーケンスについてのテスト要件がシステム的にあることがわかっているので、そのシーケンスに対するテストとして必要かもしれないと思って調査しております。まだPrismのDialog Serviceのドキュメントを読んでないので、そこがわかったらまた話が変わるかもしれませんが。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問