我有一个Autofac DI Container定义如下:
public class Bootstrapper
{
public IContainer BootStrap()
{
var builder = new ContainerBuilder();
builder.RegisterType<ItemViewModel>().AsSelf();
builder.RegisterType<EventAggregator>()
.As<IEventAggregator>()
.SingleInstance();
}
}
我定义了一个单元测试来测试删除是否从集合中删除了已删除的项目:
[Fact]
public void Should_remove_item_from_collection_when_item_is_deleted()
{
const int deletedId = 42;
// adds three items to the collection
_openItemEditViewEvent.Publish(deletedId);
_openItemEditViewEvent.Publish(8);
_openItemEditViewEvent.Publish(9);
// I've tried this:
_eventAggregatorMock.Object.GetEvent<ItemDeletedEvent>().Publish(42);
// and alternatively, this (not at the same time):
_itemDeletedEventMock.Object.Publish(42);
Assert.Equal(2,_vm.ItemEditViewModels.Count); // always fails
Assert.False(_vm.ItemEditViewModels
.Select(vm => vm.Item.Id).Contains(42), "Wrong item deleted");
}
Unit Test的构造函数初始化并将EventAggregator分配给视图模型:
_eventAggregatorMock = new Mock<IEventAggregator>();
_itemDeletedEventMock = new Mock<ItemDeletedEvent>();
_eventAggregatorMock.Setup(ea => ea.GetEvent<ItemDeletedEvent>())
.Returns(_itemDeletedEventMock.Object);
_vm = new ItemViewModel(_eventAggregatorMock.Object, */ ... /*);
在我的实际视图模型中,我订阅了该活动:
public ItemViewModel(IEventAggregator ea, /* ... */)
{
_eventAggregator.GetEvent<ItemDeletedEvent>()
.Subscribe(OnItemDeleted, true);
}
我们从未在这里遇到过断点:
public void OnItemDeleted()
{
// never happens
}
对于我的生活,我无法弄清楚我做错了什么 - 我忽略了一些事情......我是否必须设置活动的发布活动模拟?我应该使用真正的ItemDeletedEvent实例而不是模拟吗?任何帮助将不胜感激。
答案 0 :(得分:3)
=&GT;嗨斯科特,
使用EventAggregator时要测试2个ViewModel场景:
(注意:以下几行适用于PRISM的EventAggregator,我猜你正在使用它。对于其他EventAggregators,它可能会有所不同)
对于第一个场景,您必须为该事件创建一个模拟。然后,您可以在该模拟实例上验证已调用事件的Publish方法。
对于第二个场景,即您在问题中的场景,您必须在测试中使用真实事件。为什么呢?
它应该是这样的:
_itemDeletedEvent = new ItemDeletedEvent();
_eventAggregatorMock.Setup(ea => ea.GetEvent<ItemDeletedEvent>())
.Returns(_itemDeletedEvent);
现在,您的ViewModel将从EventAggregator获取此itemDeletedEvent-instance。在您的测试中,您可以在此itemDeletedEvent-instance上调用Publish-method,它将起作用。
有关这方面的更多信息,请参阅我的关于WPF和测试驱动开发的Pluralsight课程:http://www.pluralsight.com/courses/wpf-mvvm-test-driven-development-viewmodels