what method make how java mocking mockito powermock

method - variables object java



Burlándose de una variable privada que se supone que existe (1)

Después de buscar mucho más y observar todas las opciones que Mockito / Powermock tenía para ofrecer, encontré la solución (que compartiré en caso de que otros se topen con este mismo problema).

Cuando tiene variables de miembros privados que nunca se inicializan (y se supone que se crearon en otros lugares), puede usar la anotación @InjectMocks para "inyectar" los Mocks que desea en su clase que está probando.

  1. Agregue una variable en su clase de prueba para la clase que está probando y @InjectMocks la anotación @InjectMocks (org.Mockito.InjectMocks).
  2. Use @Mock anotaciones de @Mock para configurar los @Mock que desea inyectar. Use la @Mock (name = "privateVariableNameHere") para asignar el objeto Mock a la variable privada dentro de su clase que está probando.
  3. Ya sea en una función de configuración o antes de llamar a su clase, inicialice los simulacros. La forma más fácil que he encontrado es usar un método de "configuración" con la anotación @Before . Entonces, ahí dentro, llame a MockitoAnnotations.initMocks(this); para inicializar rápidamente cualquier cosa con la anotación @Mock .
  4. Defina su funcionalidad de simulacro en su método de prueba (antes de llamar al método que está probando).
  5. Usando el objeto @InjectMock , llame al método que está probando ... los simulacros DEBERÍAN estar conectados y funcionando como se definió en los pasos anteriores.

Así que para la clase de ejemplo que uso anteriormente, el código para probar / simular haría que Connection devuelto como un simulacro con el que puede hacer cualquier cosa. Basado en el ejemplo anterior en mi pregunta, este es el aspecto del código:

@RunWith(PowerMockRunner.class) @PrepareForTest({/* Static Classes I am Mocking */}) public class ExampleTest { @Mock (name = "queueFactory") //same name as private var. QueueConnectionFactory queueFactoryMock; @Mock Connection connectionMock; //the object we want returned @InjectMocks Example exampleTester; //the class to test @Before public void setup(){ MockitoAnnotations.initMocks(this); // initialize all the @Mock objects // Setup other Static Mocks } @Test public void testTestMe(){ //Mock your objects like other "normally" mocked objects PowerMockito.when(queueFactoryMock.createConnection()).thenReturn(connectionMock); //...Mock ConnectionMock functionality... exampleTester.testMe(); } }

¿Cómo puede obtener un objeto simulado en tiempo de ejecución cuando no se crea / inicializa en la clase que está probando, no es estático (patrón de singleton), o no tiene algún tipo de constructor de prueba para conectar?

En una clase para la que estoy escribiendo algunas pruebas de unidad, me he encontrado con un escenario que aún no he encontrado / resuelto. Tengo un recurso JMS (un QueueConnectionFactory para referencia, pero no debería importar), que es una variable privada de la clase que estoy probando. Dado que tiene la anotación javax.annotation.Resource , en tiempo de ejecución se supone que está disponible. Durante la prueba, no lo es, lo que crea la necesidad de burlarse de este objeto.

No es una clase estática y no se está utilizando de forma estática, si lo fuera, podría simularme fácilmente utilizando los diversos métodos de simulación estática que he encontrado. Dado que el recurso nunca se crea localmente (en un constructor o incluso en un constructor de prueba), no tengo forma de pasar un objeto simulado de modo que, en el tiempo de ejecución de la prueba, se utilice el simulacro en lugar del objeto real. ¿Cómo puedo simular este recurso para que cuando se ejecute la prueba, se usará en lugar del objeto @Resource privado en la clase que estoy probando?

Para referencia, el código está llamando a createConnection() en QueueConnectionFactory que está lanzando una excepción de puntero nulo ya que Factory no se ha inicializado / simulado.

@Stateless public class Example{ @Resource(name = "jms/exampleQCF") private QueueConnectionFactory queueFactory; ... public void testMe(){ Connection connection = queueFactory.createConnection(); ... } }