我正在尝试使用 SimpleMvvmToolkit 针对视图模型编写一些单元测试,其中一些测试需要将消息发送到消息总线以触发视图模型内的事件。问题是我似乎只能“使用”一次消息总线;发送消息的第一个测试通过,但发送消息的另外两个测试失败。但是如果我单独运行每个测试,所有三个都通过,如果我改变顺序,第一个测试,无论是哪一个,都会通过。
这是其中一项测试的示例。
[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 是否被调用。在这种情况下,需要消息总线,因为如果用户单击确定,通常会弹出一个确认对话框并发送 DeleteValidationRequestConfirmation 消息。
测试在最后一行(验证)失败,当我调试时,视图模型中消息的处理程序永远不会执行,因此看起来消息从未真正发送过。同样,仅当测试不是向总线发送消息的第一个测试时才会失败。如果它单独执行或者是第一个执行,则测试通过。
有任何想法吗?所有测试都是独立的,并且不共享测试类的任何属性或变量,所以我看不出它们如何相互踩踏。
编辑:我使用反射调用消息通常会触发的视图模型上的受保护方法;这得到了我想要的代码覆盖率,它只是没有验证视图模型是否正确响应消息。
编辑 2:废话,视图模型上的 PropertyChanged 事件也发生了同样的事情。事件处理程序仅在测试独立运行或第一个运行时触发。