SimpleMvvmToolkitを使用してビューモデルに対していくつかの単体テストを作成しようとしています。これらのテストのいくつかでは、ビューモデル内でイベントを発生させるためにメッセージをメッセージバスに送信する必要があります。問題は、メッセージバスを「使用」できるのは1回だけのように見えることです。メッセージを送信する最初のテストは成功しますが、メッセージを送信する他の2つのテストは失敗します。しかし、各テストを個別に実行すると、3つすべてが合格し、順序を変更すると、最初のテストは、どちらであっても合格します。
これは、テストの1つのサンプルです。
[TestMethod]
public void DeleteRequest()
{
// mock the driver transaction service
var driverTransactionService =
new Mock<Services.IDriverTransactionService>();
var viewModel = new ValidationRequestViewModel(
driverTransactionService.Object);
driverTransactionService.Setup(dts =>
dts.DeleteValidationRequest(It.IsAny<Action<int>>(),
It.IsAny<Action<Exception>>(),
It.IsAny<int>()))
.Callback((Action<int> action, Action<Exception> ex, int id) =>
action.Invoke(requestId));
// make a validation request and add to the collection
var validationRequest = new ValidationRequest...
var collection = viewModel.ValidationRequestView.SourceCollection as
ObservableCollection<ValidationRequest>;
collection.Add(validationRequest);
// delete the validation request; send the confirmation message as if
// the user clicked yes
viewModel.DeleteValidationRequest(validationRequest);
MessageBus.Default.Notify(
NotificationMessages.DeleteValidationRequestConfirmation,
this, new NotificationEventArgs<String>(null, null));
// verify the service call was made
driverTransactionService.Verify(dts =>
dts.DeleteValidationRequest(It.IsAny<Action<int>>(),
It.IsAny<Action<Exception>>(), requestId));
}
そのため、サービスのモック(WCFサービスのラッパー)を作成し、サービスのDeleteValidatonRequestが呼び出されていることを確認しています。この場合、ユーザーが[OK]をクリックすると、通常は確認ダイアログがポップアップしてDeleteValidationRequestConfirmationメッセージを送信するため、メッセージバスが必要です。
テストは最後の行(検証)で失敗し、デバッグすると、ビューモデルのメッセージのハンドラーが実行されないため、メッセージが実際に送信されないように見えます。繰り返しますが、これは、テストがバスにメッセージを送信する最初のテストではない場合にのみ失敗します。単独で実行するか、最初に実行する場合、テストは合格です。
何か案は?すべてのテストは独立しており、テストクラスのプロパティや変数を共有していないため、どのように相互にステップできるかわかりません。
編集:リフレクションを使用して、メッセージが通常起動するビューモデルの保護されたメソッドを呼び出しました。これにより、必要なコードカバレッジが得られますが、ビューモデルがメッセージに正しく応答していることを確認できません。
編集2:クラップ、ビューモデルのPropertyChangedイベントでも同じことが起こっています。イベントハンドラーは、テストが独立して実行されるか、最初の場合にのみ起動します。