I'm a .NET guy - and I mainly code in C#.
Since C# 3.0, we can leverage lambda expressions and expression trees to use static reflection. For example, it is possible to implement GetMethodName
in the following snippet to return the name of the method passed in parameter:
string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"
Now, when I look at Mockito samples (or EasyMock ones) in the java world, I see:
LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");
How does it work?
How does the when
method work ? How does it interpret mockedList.get(0)
as a call to the get method with 0 passed as parameter and not as a value?
Mocking libraries don't typically work with expression trees. They build a type which implements the appropriate interface and responds to method calls either by recording them or validating them and returning the preprogrammed responses. This is usually done with either a proxy (e.g. RealProxy in .NET, Proxy in Java) or with dynamic code generation.
In the case of EasyMock, it uses Proxy
(for interfaces, anyway), as you can see in the source code: look at org.easymock.internal.JavaProxyFactory
.
Java mock libraries usually work like this:
When you create a mock, an actual proxy is created (be it from an interface or a sub-class), the instance is in "recording mode". This means that any subsequent call is recorded (method name, parameters, return expected). Notice that the proxy in recording mode does actually nothing but record the calls. There is no reflection per-se involved. No metadata discovery, etc. Of course these libraries do some tricks (such as storing invocations in a thread-local variable to handle methods that return void) but the idea remains the same.
Then, when the "replay mode" is started, the mock instance simply checks the expectations from the list of invocations (method+parameters & return values).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With