【问题标题】:How does "static reflection" work in java? (ex. in mockito or easymock)“静态反射”在 java 中是如何工作的? (例如在 mockito 或 easymock 中)
【发布时间】:2009-03-09 13:55:20
【问题描述】:

我是一名 .NET 人员 - 我主要使用 C# 编写代码。

从 C# 3.0 开始,我们可以利用 lambda 表达式和表达式树来使用 static reflection。比如可以在下面的sn-p中实现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) 解释为以0 作为参数而不是值传递的get 方法的调用

【问题讨论】:

    标签: c# java reflection easymock mockito


    【解决方案1】:

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

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

    【讨论】:

    • 代理与接口一起使用。真正的模拟框架到他们自己的代码生成。
    • 在 .NET 中,强类型模拟框架使用表达式树(参见 Moq 和 Rhino 模拟)以及动态代理。但是在这里我仍然不清楚如何(即使使用代理)安全地设置模拟。如果我输入“when(mockedList.get(0) + mockedList.get(2)).thenReturn(42)”会怎样?
    • Rhino Mocks 早在表达式树出现之前就已经存在了。在某些情况下,它可能现在 使用表达式树,但它并不总是 这样做。 (它在 .NET 2.0 中仍然有效。)如果在指定最后一个结果之前再次调用 mock,结果取决于 mock 的模式。
    • (无论如何,IIRC。)在严格模式下,录制阶段将失败,因为您没有指定适当的返回值。在其他一些模式下,它将返回默认值。这完全取决于模拟框架。它只看到两个 get(...) 调用,然后是一个 thenReturn() 调用。
    • @Tom:你需要生成代码来模拟类,但并不是所有的模拟框架都允许这样做,至少开箱即用。如果你只是模拟接口,Proxy 很好。我不记得我上次嘲笑一堂课是什么时候了 :)
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      我从未使用过 mockito 或 easymock,但我认为该调用不会像您认为的那样做。它不会以任何特殊方式解释mockedList.get(0)get方法在mockedList对象上正常执行,其结果交给when

      【讨论】:

        【解决方案4】:

        mockedList.get(0) 是方法调用的语法,并且确实如此。该方法的作用并不完全清楚。 mockedList 的运行时类型将是 LinkedList 的子类,由 mock 方法返回,可以在模拟框架认为合适的任何情况下实现。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多