はじめに
自分用メモですが、同じ状況の方の参考になれば幸いです。
普段は WPF と ASP.NET の API 開発を長年やっています。
前提
WPFではCommunityToolkit.Mvvm
のパッケージを使用しています。
ChatGPTに聞いたこと
WPFでViewModelを単体テストしたい
結論
ViewModelをDIに登録することにしました。
コンストラクタで Ioc コンテナから取得し、DataContext
に登録します。初期化処理が必要な場合は、このタイミングで行います。
なお、この方法では XAML のインテリセンスは利用できなくなります。工夫すれば回避できるようですが、複雑化して理解が追いつかなくなるのは避けたいので、割り切って切り捨てました。最もシンプルでわかりやすい形を選びました。
/// ViewModelはTransientで登録
services.AddTransient<MainViewModel>();
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
var viewModel = Ioc.Default.GetRequiredService<MainViewModel>();
_ = viewModel.InitializeAsync();
DataContext = viewModel;
InitializeComponent();
}
}
MessageBox
は IMessageBox
インターフェース経由で利用し、外部依存を排除します。
どうしても ViewModel から View を操作する必要がある場合には、CommunityToolkit.Mvvm の弱参照(WeakReferenceMessenger) を使用します。
さらに、RelayCommand
は単体テストを行いやすくするために internal
に変更しました。
[RelayCommand]
internal async Task PushAsync()
{
_messageBox.Show("Push!!");
}