如何验证使用Moq订阅的事件

时间:2011-02-21 06:17:23

标签: unit-testing silverlight-4.0 moq

我正在使用MVVM模式和Silverlight 4.0和Moq进行测试。 在视图模型构造函数中,我传递了一个IEventAggregator对象。该对象用于订阅名为SelectionChangedEvent的事件。

在测试方法中,我这样做:

this.selectedEvent = new Mock<SelectionChangedEvent>();
this.eventAggregator.Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(this.selectedEvent.Object);
var viewModel = new ViewModel(this.eventAggregator);

我想测试在调用构造函数时事件是否已订阅。 我该如何验证?

1 个答案:

答案 0 :(得分:4)

[免责声明:我无法在Silverlight下测试]

这是一个可能的解决方案,它基本上执行回调以在事件上调用Subscribe时设置外部布尔值。请参阅下面的评论。

[Test]
public void Constructor_CallsSubscribeOnSelectionChangeEvent()
{
  var subscribeCalled = false;
  var selectedEvent = new Mock<SelectionChangedEvent>();
  var eventAggregator = new Mock<IEventAggregator>();

  selectedEvent
    .Setup(x => x.Subscribe(
      It.IsAny<Action<object>>(),
      It.IsAny<ThreadOption>(),
      It.IsAny<bool>(),
      It.IsAny<Predicate<object>>()))
    .Callback<Action<object>, ThreadOption, bool, Predicate<object>>
      ((action, option, f, pred) => { subscribeCalled = true; });

  eventAggregator
    .Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(selectedEvent.Object);

  var viewModel = new ViewModel(eventAggregator.Object);

  Assert.That(subscribeCalled, Is.EqualTo(true));
}

以上是非常难看的,主要是因为事件的Subscribe方法的唯一可模拟(虚拟)重载需要四个参数,并且Callback()的参数类型不能自动推断 - 这导致很多“无关的”代码。

另一种方法是改为模拟EventBase.InternalSubscribe,它只接受一个参数;但由于该方法受到保护,这种方法有其自己的注意事项。