tags:

views:

335

answers:

2

I'm trying to mock MouseButtonEventArgs.GetPosition() with Moq, but I keep receiving this error:

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)

Here is the code where I setup my mock:

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

I'm not sure what I'm doing wrong, does anyone have any suggestions for how to do this?

+7  A: 

This error means that you're trying to fake a method which is not declared as virtual.

Moq generates a type at runtime, in order to be able to fake it the generated type inherits the from original type and overrides its virtual methods. Since non-virtual methods cannot be overridden (this is the spec of the language, it's not a limitation of Moq) it is not possible to fake these methods.

As a solution you can wrap the class that raises the event that sends MouseButtonEventArgs and pass a class of your own that declares the relevant methods as virtual. I think it might be a little challenge in your case but it's worth trying.

Another solution can be to use isolation framework that enables faking non-virtual methods. Typemock Isolator foe example is a framework that can do this. Isolator uses different mechanism so it allows faking this kind of methods.

Disclaimer - I work at Typemock

Elisha
+2  A: 

MouseButtonEventArgs.GetPosition() is a non-abstract, non-virtual method. You cannot mock it with MOQ, Rhino Mocks, or most other mocking frameworks.

This is because of the way C#/.NET are structured: all methods are non-virtual by default. Compare that with Java, where all methods are virtual by default.

I have not used it, but I understand that Type Mock will let you do this because it mocks by actually rewriting your code rather than simple inheritance the way most other mocking frameworks do.

Randolpho