问题
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?
回答1:
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 for 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
回答2:
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.
来源:https://stackoverflow.com/questions/1918208/why-cant-i-mock-mousebuttoneventargs-getposition-with-moq