TypeMock: How to Make Reflective Mocks More Natural
Like I said before, this as been on the back of my mind for a while.
A while back I introduced a way to get the MethodInfo of a method in a strongly typed way using LINQ, and that's how I'm going to make Reflective Mocks more Natural.
Well, it's as easy as this:
public static class MockExtender { public static IParameters ExpectAndReturn<T1, T2, TResult>(this IMockControl mock, Expression<Func<T1, T2, TResult>> expression, object ret, params Type[] genericTypes) { return mock.ExpectAndReturn((expression.Body as MethodCallExpression).Method.Name, ret, genericTypes); } }
(For now, I'll leave to someone else the implementation of the rest of the overloads)
With this implementation it's possible to handle static classes (a limitation of Fredrik's implementation).
As for private methods, just let Visual Studio (2008, in this sample) and TypeMock do their magic.
So, to test this class:
public static class Class1 { public static string PublicMethod(string param1, int param2) { return PrivateMethod(param2, param1); }<SPAN style="COLOR: blue">private static string </SPAN>PrivateMethod(<SPAN style="COLOR: blue">int </SPAN>param2, <SPAN style="COLOR: blue">string </SPAN>param1) { <SPAN style="COLOR: blue">throw new </SPAN><SPAN style="COLOR: #2b91af">NotImplementedException</SPAN>(); }
}
[TestMethod()] public void PublicMethodTest() { string param1 = "param"; int param2 = 5; string expected = "return"; string actual;<SPAN style="COLOR: #2b91af">Mock </SPAN>targetMock = <SPAN style="COLOR: #2b91af">MockManager</SPAN>.Mock(<SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: #2b91af">Class1</SPAN>)); targetMock.ExpectAndReturn((<SPAN style="COLOR: blue">int </SPAN>i, <SPAN style="COLOR: blue">string </SPAN>s) => ClassLibrary1.<SPAN style="COLOR: #2b91af">Class1_Accessor</SPAN>.PrivateMethod(i, s), expected).Args(param2, param1); actual = <SPAN style="COLOR: #2b91af">Class1</SPAN>.PublicMethod(param1, param2); <SPAN style="COLOR: #2b91af">Assert</SPAN>.AreEqual(expected, actual);
}
How about this for clean and simple?