我是一个.NET家伙 - 我主要用C#编写代码。

从C#3.0开始,我们可以利用lambda表达式和表达式树来使用静态反射。例如,可以在以下代码段中实现 GetMethodName ,以返回在参数中传递的方法的名称:

string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"

现在,当我在java世界中查看Mockito样本(或EasyMock样本)时,我看到:

LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");

它是如何运作的?

when 方法如何工作?它是如何将 mockedList.get(0)解释为对get方法的调用,其中0作为参数传递而不是作为值?

有帮助吗?

解决方案

模拟库通常不适用于表达式树。它们构建了一个实现适当接口的类型,并通过记录它们或验证它们并返回预编程的响应来响应方法调用。这通常通过代理完成(例如 RealProxy ,在.NET中,代理在Java中)或动态代码生成。

对于EasyMock,它使用 Proxy (对于接口,无论如何),正如您在源代码中看到的那样:查看 org.easymock.internal.JavaProxyFactory

其他提示

Java模拟库通常像这样工作:

当您创建模拟时,会创建一个实际的代理(无论是来自接口还是子类),该实例处于“记录模式”。这意味着记录任何后续调用(方法名称,参数,预期返回)。请注意,处于录制模式的代理实际上只记录了呼叫。没有任何反思本身。没有元数据发现等。当然这些库做了一些技巧(比如在线程局部变量中存储调用来处理返回void的方法)但是这个想法仍然是相同的。

然后,当“重放模式”时,启动时,模拟实例只是检查调用列表中的期望(方法+参数和返回值)。

我从未与mockito或easymock合作,但我不认为这个电话会按照你的想法行事。它不以任何特殊方式解释 mockedList.get(0)。方法 get 通常在 mockedList 对象上执行,结果在时传递给

mockedList.get(0)是方法调用的语法,并且正是这样做的。该方法的作用并不完全清楚。 mockedList 的运行时类型将是 mock 方法返回的 LinkedList 的子类,可以实现模拟框架认为合适的方式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top