【问题标题】:Why can't I mock MouseButtonEventArgs.GetPosition() with Moq?为什么我不能用 Moq 模拟 MouseButtonEventArgs.GetPosition()?
【发布时间】:2009-12-16 22:19:53
【问题描述】:

我正在尝试使用 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));

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

【问题讨论】:

    标签: c#-3.0 moq


    【解决方案1】:

    这个错误意味着你试图伪造一个没有声明为virtual的方法。

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

    作为一种解决方案,您可以包装引发发送 MouseButtonEventArgs 的事件的类,并传递一个您自己的类,该类将相关方法声明为 virtual。我认为这对你来说可能有点挑战,但值得一试。

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

    免责声明 - 我在 Typemock 工作

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多