1

我们已经使用 Moq 两个月了。但是有一个问题无法以某种方式解决。

在视觉工作室中,所有测试都成功了。在构建服务器上,有几个测试失败了。他们的共同点是,他们使用“raise”方法来抛出一个事件。我们的构建服务器测试混淆了发现混淆错误的好方法。像“Setup(something).Returns(something)”这样的每个“正常”期望都有效。只有 raise 事件失败。堆栈跟踪如下所示:

MESSAGE:
Test method Ade.Graphic.Presenter.Test.RoutingEngineTest.TestRouteOverLadderLinesWithFbd threw exception: 
System.ArgumentException: Could not locate event for attach or detach method Void ᜀ(ᦜ[ᢈ]).
+++++++++++++++++++
STACK TRACE:
    bei Moq.Extensions.GetEvent[TMock](Action`1 eventExpression, TMock mock)
   bei Moq.Mock`1.Raise(Action`1 eventExpression, EventArgs args)
   bei Ade.Graphic.Presenter.Test.RoutingEngineTest.TestRouteOverLadderLinesWithFbd()

代码是:

documentEventHandler.Raise(stub => stub.DocumentChanged += null,
                                                new DocumentChangeEventArgs(DocumentChangeTypes.ViewUpdate));

我们不知道上面的代码和这个有什么区别

eventHandler.SetupGet(stub => stub.DocumentChangeNotify).Returns(documentEventHandler.Object);

因为这段代码工作正常。

有没有人有同样的问题,或者至少可以说出有什么区别?

4

1 回答 1

2

错误可能来自(不确定未测试)事件(即 DocumentChanged)实际上是作为 2 个访问器生成的: add_DocumentChanged 和 remove_DocumentChanged 。这类似于具有 get 和 set 访问器的属性。

混淆器所做的最有可能是重命名此 add_DocumentChanged 和 remove_DocumentChanged。但是,查看 moq 源代码,我可以看到 moq 依赖于保持相同名称的事件访问器:

 var ev = addRemove.DeclaringType.GetEvent(
                            addRemove.Name.Replace("add_", string.Empty).Replace("remove_", string.Empty));

ev == null 在这种情况下,这会引发错误。

在您的第二个示例中,您使用的是未分解为 add_ 和 remove_ 访问器的委托。

你最好不要混淆事件。

于 2013-05-28T20:49:27.987 回答