我使用复合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 ...”
知道我做错了吗?
答案 0 :(得分:0)
在您的代码中,似乎永远不会使用eventAggregatorMock
实例。我猜你需要在容器中注册它,以便controllerToTest
使用它。
答案 1 :(得分:0)
您似乎在单元测试中测试过多。你不应该需要一个容器,你应该只创建你的控制器提供模拟依赖,因为你应该只在单元测试中测试1件事(你不需要测试DI框架的工作原理,因为它通常会这样做;-) )。它还将确保您提供正确的模拟,现在您的代码中不清楚Mark Seemann在其答案中指出的。
您可以尝试在开头设置问题中的方法调用。有时它似乎有助于moq适当地验证课程。在这种情况下,您可能还希望在构造函数中将模拟行为设置为Strict
,这样您将无法对模拟的其他意外调用进行测试。
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,它将无法工作;这通常不会在单元测试中运行。