2009-03-09 13 views
5

Soy un chico .NET - y principalmente codigo en C#.¿Cómo funciona la "reflexión estática" en Java? (por ejemplo, en mockito o easymock)

Desde C# 3.0, podemos aprovechar las expresiones lambda y los árboles de expresión para usar static reflection. Por ejemplo, es posible implementar GetMethodName en el siguiente fragmento de código para devolver el nombre del método que se pasa en el parámetro:

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

Ahora, cuando miro muestras Mockito (o los EasyMock) en el mundo Java, yo ver:

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

¿Cómo funciona?

¿Cómo funciona el método when? ¿Cómo interpreta mockedList.get(0) como una llamada al método get con 0 pasado como parámetro y no como un valor?

Respuesta

5

Las bibliotecas de burla no suelen funcionar con árboles de expresiones. Construyen un tipo que implementa la interfaz adecuada y responde a las llamadas al método, ya sea registrándolas o validándolas y devolviendo las respuestas preprogramadas. Esto generalmente se hace con un proxy (por ejemplo, RealProxy en .NET, Proxy en Java) o con generación de código dinámico. En el caso de EasyMock, usa Proxy (para interfaces, de todos modos), como puede ver en el código fuente: consulte org.easymock.internal.JavaProxyFactory.

+0

Proxy en trabajos con interfaces. Marcos burlones reales para su propia generación de código. –

+0

En .NET, los marcos burlones fuertemente tipados usan árboles de expresión (véanse los simulacros de Moq y Rhino) y, de hecho, proxies dinámicos. Pero aquí todavía no está claro cómo (incluso con proxies) puede configurar el simulacro de forma segura. ¿Qué ocurre si escribo "cuándo (mockedList.get (0) + mockedList.get (2)). Then luego Return (42)"? –

+0

Rhino Mocks existía mucho antes que los árboles de expresión. Puede usar árboles de expresión * ahora * en algunos casos, pero no * siempre * lo hace. (Todavía funciona en .NET 2.0.) Si realiza otra llamada al simulacro antes de especificar el resultado del último, los resultados dependen del modo del simulacro. –

2

Nunca he trabajado con mockito o easymock, pero no creo que la llamada haga lo que crees que hace. No interpreta mockedList.get(0) de ninguna manera especial. El método get se ejecuta normalmente en el objeto mockedList y el resultado se entrega en when.

1

mockedList.get(0) es la sintaxis de una llamada a método, y hace exactamente eso. Lo que hace ese método no es exactamente claro. El tipo de tiempo de ejecución de mockedList será una subclase de LinkedList devuelta por el método mock, que se puede implementar de la forma que lo crea conveniente.

4

Java bibliotecas simulacros por lo general trabajan de esta manera:

Al crear una maqueta, se crea un proxy real (ya sea desde una interfaz o una subclase), la instancia está en "modo de grabación". Esto significa que cualquier llamada subsiguiente se registrará (nombre del método, parámetros, retorno esperado). Tenga en cuenta que el proxy en modo de grabación no hace nada más que grabar las llamadas. No hay reflexión en sí misma involucrada. Sin descubrimiento de metadatos, etc. Por supuesto, estas bibliotecas realizan algunos trucos (como el almacenamiento de invocaciones en una variable local de subprocesos para manejar los métodos que devuelven el vacío), pero la idea sigue siendo la misma.

Luego, cuando se inicia el "modo de reproducción", la instancia simulada simplemente verifica las expectativas de la lista de invocaciones (método + parámetros & valores de retorno).

Cuestiones relacionadas