method compatible and java mockito junit4 powermockito

java - compatible - Mockito: simulacro de inicialización de campo privado



powermock and mockito compatible versions (6)

¿Cómo puedo burlarme de una variable de campo que se está inicializando en línea?

p.ej

class Test { private Person person = new Person(); ... public void testMethod() { person.someMethod(); ... } }

Aquí quiero burlarme de person.someMethod () mientras prueba el método - Test # testMethod.

para lo cual necesito burlarme de la inicialización de la variable persona. ¿Cualquier pista?

EDITAR: No tengo permiso para modificar la clase Persona.


Bastante tarde para la fiesta, pero me llamó la atención aquí y recibí ayuda de un amigo. La cosa era no usar PowerMock. Esto funciona con la última versión de Mockito.

Mockito viene con este org.mockito.internal.util.reflection.FieldSetter .

Lo que básicamente hace es ayudarlo a modificar campos privados utilizando la reflexión.

Así es como lo usas:

@Mock private Person mockedPerson; private Test underTest; // ... @Test public void testMethod() { FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person"), mockedPerson); // ... verify(mockedPerson).someMethod(); }

De esta manera, puede pasar un objeto simulado y luego verificarlo más tarde.

Referencia:

https://www.codota.com/code/java/methods/org.mockito.internal.util.reflection.FieldSetter/set


El siguiente código se puede usar para inicializar el mapeador en la simulación del cliente REST. El campo del mapper es privado y debe configurarse durante la configuración de la prueba de la unidad.

import org.mockito.internal.util.reflection.FieldSetter; new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());


En caso de que use Spring Test, intente org.springframework.test.util.ReflectionTestUtils

ReflectionTestUtils.setField(testObject, "person", mockedPerson);


Mockito viene con una clase auxiliar para ahorrarle un código de placa de caldera de reflexión:

import org.mockito.internal.util.reflection.Whitebox; //... @Mock private Person mockedPerson; private Test underTest; // ... @Test public void testMethod() { Whitebox.setInternalState(underTest, "person", mockedPerson); // ... }

Actualización: Desafortunadamente, el equipo de mockito decidió eliminar la clase en Mockito 2. Por lo tanto, debe volver a escribir su propio código de reflexión, usar otra biblioteca (por ejemplo, Apache Commons Lang ) o simplemente robar la clase Whitebox (tiene licencia MIT ).

Actualización 2: JUnit 5 viene con sus propias clases ReflectionSupport y AnnotationSupport que pueden ser útiles y evitar que accedas a otra biblioteca.


Usando la guía de @ Jarda puede definir esto si necesita configurar la variable con el mismo valor para todas las pruebas:

@Before public void setClientMapper() throws NoSuchFieldException, SecurityException{ FieldSetter.setField(client, client.getClass().getDeclaredField("mapper"), new Mapper()); }

Pero tenga en cuenta que establecer valores privados para que sean diferentes debe manejarse con cuidado. Si son privados son por alguna razón.

Ejemplo, lo uso, por ejemplo, para cambiar el tiempo de espera de un sueño en las pruebas unitarias. En ejemplos reales, quiero dormir durante 10 segundos, pero en la prueba de unidad estoy satisfecho si es inmediato. En las pruebas de integración, debe probar el valor real.


Ya encontré la solución a este problema que olvidé publicar aquí.

@RunWith(PowerMockRunner.class) @PrepareForTest({ Test.class }) public class SampleTest { @Mock Person person; @Test public void testPrintName() throws Exception { PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person); Test test= new Test(); test.testMethod(); } }

Los puntos clave de esta solución son:

  1. Ejecutar mis casos de prueba con PowerMockRunner: @RunWith(PowerMockRunner.class)

  2. Indique a Powermock que prepare Test.class para la manipulación de campos privados: @PrepareForTest({ Test.class })

  3. Y finalmente burlarse del constructor para la clase Persona:

    PowerMockito.mockStatic(Person.class); PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);