为什么我不能用Moq模拟MouseButtonEventArgs.GetPosition()?

时间:2009-12-16 22:19:53

标签: c#-3.0 moq

我正在尝试使用Moq模拟MouseButtonEventArgs.GetPosition(),但我一直收到此错误:

System.ArgumentException: Invalid setup on a non-overridable member:
m => m.GetPosition(It.IsAny<IInputElement>())

at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo)  
at Moq.Mock.<>c__DisplayClass12`2.<Setup>b__11()
at Moq.PexProtector.Invoke<T>(Func`1 function)
at Moq.Mock.Setup<T1,TResult>(Mock mock, Expression`1 expression)
at Moq.Mock`1.Setup<TResult>(Expression`1 expression)

以下是我设置模拟的代码:

    var mockMbEventArgs = new Mock<MouseButtonEventArgs>();
    mockMbEventArgs.Setup(m => m.GetPosition(It.IsAny<IInputElement>())).Returns(new Point(10.0, 10.0));

我不确定我做错了什么,有没有人对如何做到这一点有任何建议?

2 个答案:

答案 0 :(得分:9)

此错误意味着您正在尝试伪造未声明为虚拟的方法。

Moq在运行时生成一个类型,为了能够伪造它,生成的类型继承原始类型并覆盖其虚拟方法。由于无法覆盖非虚方法(这是语言的规范,它不是Moq的限制),因此不可能伪造这些方法。

作为一种解决方案,您可以包装引发 MouseButtonEventArgs 的事件的类,并传递您自己的类,将相关方法声明为 virtual 。我认为在你的情况下这可能是一个小挑战,但值得尝试。

另一种解决方案可以是使用隔离框架来实现伪造非虚方法。例如,Typemock Isolator是一个可以做到这一点的框架。隔离器使用不同的机制,因此它允许伪造这种方法。

免责声明 - 我在Typemock工作

答案 1 :(得分:2)

MouseButtonEventArgs.GetPosition()是一种非抽象的非虚方法。你不能用MOQ,Rhino Mocks或大多数其他模拟框架来模拟它。

这是因为C#/ .NET的结构方式:默认情况下所有方法都是非虚拟的。与Java相比,默认情况下所有方法都是虚拟的。

我没有使用它,但我知道Type Mock会让你这样做,因为它通过实际重写代码而不是像大多数其他模拟框架那样的简单继承来进行模拟。