为什么我的Moq IEventAggregator验证失败?

时间:2009-07-27 09:29:37

标签: wpf unit-testing moq unity-container eventaggregator

我使用复合WPF(Prism),我正在尝试单元测试我的Controller实际上订阅了一个复合事件。

我的订阅代码如下所示......

//Init Events.
this.eventAggregator.GetEvent<PlantTreeNodeSelectedEvent>().Subscribe(
    ShowNodeDetails, ThreadOption.UIThread);

我的单元测试代码如下(我使用Moq作为我的Mocking Framework,Unity作为我的DI框架)...

Mock<PlantTreeNodeSelectedEvent> eventBeingListenedTo = new Mock<PlantTreeNodeSelectedEvent>();
eventAggregatorMock.Setup(e => e.GetEvent<PlantTreeNodeSelectedEvent>()).Returns(eventBeingListenedTo.Object);


//Initialize the controller to be tested.
IPlantTreeController controllerToTest = container.Resolve<IPlantTreeController>();


//Verify.
eventBeingListenedTo.Verify(
    e => e.Subscribe(It.IsAny<Action<string>>(), ThreadOption.UIThread));

这个订阅方法被调用(我已经通过运行调试器进行了验证),但是验证始终失败,并且“未在模拟上执行调用:e =&gt; e.Subscribe ...”

知道我做错了吗?

3 个答案:

答案 0 :(得分:0)

在您的代码中,似乎永远不会使用eventAggregatorMock实例。我猜你需要在容器中注册它,以便controllerToTest使用它。

答案 1 :(得分:0)

  1. 您似乎在单元测试中测试过多。你不应该需要一个容器,你应该只创建你的控制器提供模拟依赖,因为你应该只在单元测试中测试1件事(你不需要测试DI框架的工作原理,因为它通常会这样做;-) )。它还将确保您提供正确的模拟,现在您的代码中不清楚Mark Seemann在其答案中指出的。

  2. 您可以尝试在开头设置问题中的方法调用。有时它似乎有助于moq适当地验证课程。在这种情况下,您可能还希望在构造函数中将模拟行为设置为Strict,这样您将无法对模拟的其他意外调用进行测试。


  3. eventBeingListenedTo.Setup(e => e.Subscribe(It.IsAny<Action<string>>(), ThreadOption.UIThread));
    

答案 2 :(得分:0)

使用像这样的模拟聚合器(对于Rhino.Mocks) http://adammills.wordpress.com/2010/12/13/auto-mocking-eventaggregator/

如果你使用ThreadOption.UIThread,它会调用Dispatcher.Invoke,如果没有Message Loop,它将无法工作;这通常不会在单元测试中运行。