代码之家  ›  专栏  ›  技术社区  ›  Romain Verdier

“静态反射”是如何在Java中工作的?(例如在Mockito或Easymock)

  •  5
  • Romain Verdier  · 技术社区  · 15 年前

    我是一个.NET用户-我主要用C编码。

    因为C 3.0,我们可以利用lambda表达式和表达式树来使用 static reflection . 例如,可以实现 GetMethodName 在以下代码段中返回传入参数的方法的名称:

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

    现在,当我在Java世界中查看McCito to示例(或EasyMoCK)时,我看到:

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

    它是如何工作的?

    如何 when 方法工作?它怎么解释 mockedList.get(0) 作为 以0作为参数传递给get方法的调用 而不是作为一种价值?

    4 回复  |  直到 15 年前
        1
  •  5
  •   Jon Skeet    15 年前

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

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

        2
  •  4
  •   Antonio    15 年前

    Java模拟库通常是这样工作的:

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

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

        3
  •  2
  •   Bombe    15 年前

    我从来没有和Mockito或Easymock合作过,但我不认为这个电话会像你想象的那样。它不能解释 mockedList.get(0) 以任何特殊的方式。方法 get 在执行 mockedList 对象正常,并且 结果 交给 when .

        4
  •  1
  •   Tom Hawtin - tackline    15 年前

    mockedList.get(0) 是一个方法调用的语法,并执行该操作。这种方法的作用还不完全清楚。 mockedList 的运行时类型将是 LinkedList 返回的 mock 方法,该方法可以在模拟框架认为合适的情况下实现。