私はいくつかの解決策について読んでいるので、それらはすべて新しいビューとそのビューモデルを実装しようとします...など。しかし、ユーティリティはあまりよくわかりません。
メッセージボックスを開くメソッドをどのように単体テストしますか?
仕様が変更され、別の(カスタム)メッセージボックスを使用する必要がある場合、またはエラーのみをログに記録する必要がある場合(後で要約レポートに表示される)はどうなりますか?msgBox.Show
次に、すべての呼び出しを見つけて置き換える必要があります。
つまり、ユーザーに何かを通知したい場合、結果はユーザーの決定に依存しますが、テスト(GUIとロジック)をどのように分離できますか?
決定が必要なときにトリガーされるイベントを作成する。その後、あなたは決定を取り戻しています。あなたはそれがどこから来たのか気にしません。
どちらの場合も、私の結果はユーザーの決定に依存するためです。この場合、どうすればアプリケーションをテストできますか?
非常に簡単です。ユーザーの返信をあざけるだけです。考えられる両方のシナリオをテストできる(そしておそらくそうすべきである)ので、2つの「偽の」イベントハンドラーをアタッチするだけです。1つは肯定的な決定を返し、もう1つは否定的な決定を返します。
たとえば、http://joyfulwpf.blogspot.com/2009/05/mvvm-communication-among-viewmodels.htmlを参照してください。
通知機能を注入するというアスピリンの提案も、優れた設計上の選択です。
いくつかの大ざっぱな、過度に単純化された実装:
using System;
using System.Windows.Forms;
namespace Demo
{
public delegate bool DecisionHandler(string question);
/// <remarks>
/// Doesn't know a thing about message boxes
/// </remarks>
public class MyViewModel
{
public event DecisionHandler OnDecision;
private void SomeMethod()
{
// something...
// I don't know who or what replies! I don't care, as long as I'm getting the decision!
// Have you made your decision for Christ?!! And action. ;)
var decision = OnDecision("Do you really want to?");
if (decision)
{
// action
}
else
{
// another action
}
}
}
class Program
{
static void Main(string[] args)
{
// this ViewModel will be getting user decision from an actual message box
var vm = new MyViewModel();
vm.OnDecision += DecideByMessageBox;
// unlike that one, which we can easily use for testing purposes
var vmForTest = new MyViewModel();
vmForTest.OnDecision += SayYes;
}
/// <summary>
/// This event handler shows a message box
/// </summary>
static bool DecideByMessageBox(string question)
{
return MessageBox.Show(question, String.Empty, MessageBoxButtons.YesNo) == DialogResult.Yes;
}
/// <summary>
/// Simulated positive reply
/// </summary>
static bool SayYes(string question)
{
return true;
}
}
}