es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Es posible realizar espionaje anidado con Mockito?

Supongamos que tengo un objeto como este:

public ClassA() {
   public void start() {
      ...
      ClassB algo = getSomeStuff();
      ...
   }

   protected ClassB getSomeStuff() {
      return new ClassB(render, response);
   }
}

Luego estoy intentando hacer algunas pruebas unitarias de esta manera, donde espío una llamada al método en un objeto espía:

@Spy private ClassA classA;
@Mock private ClassC classC;
...
@Test 
void test1() {
    ClassB classB = spy(classA.getSomeStuff());
    doReturn(classC).when(classB).getResults();

    classA.start();
}

Cuando ejecuto esta prueba y llego a esta última línea, puedo ver en mi depurador que no está devolviendo classC.

¿Es esto porque no es posible hacer espionaje anidado? ¿O hay algo mal en mi configuración? ¿O debería abordar esto de manera diferente?

Detalles:
– junit: 5.7.0
– mockito: 3.12.4

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Posibles problemas con espionaje anidado y cómo abordar esta situación usando Mockito:

    1. Limitaciones en Mockito: El espionaje anidado, como en el ejemplo proporcionado, puede no funcionar como se espera en Mockito porque puede llevar a un comportamiento inesperado y resultados incorrectos. La documentación de Mockito indica que “el espionaje en métodos reales puede ser peligroso. La lógica real se ejecuta, por lo que si algo está mal, tendrá que depurar problemas complicados”. Por lo tanto, se recomienda evitar objetos espías anidados y, en su lugar, crear instancias de espía separadas para cada objeto.
    2. Enfoque alternativo: Un enfoque alternativo podría ser refactorizar el código en ClassA para que la creación de ClassB se extraiga en un método separado que se pueda mockear o espiar fácilmente. Por ejemplo:

      public ClassA() {
       public void start() {
           ...
           ClassB something = createClassB(render, response);
           ...
       }
      
       protected ClassB createClassB(Render render, Response response) {
          return new ClassB(render, response);
       }
      }
      

      Luego, en la prueba, puede espiar ClassA y hacer mock al método createClassB para devolver una instancia espía de ClassB con el comportamiento deseado:

      @Spy private ClassA classA;
      
      @Mock private ClassC classC;
      
      ...
      
      @Test
      void test1() {
        ClassB spiedB = spy(new ClassB(render, response));
        doReturn(classC).when(spiedB).getResults();
      
        doReturn(spiedB).when(classA).createClassB(render, response);
      
        classA.start();
      }
      

      Este enfoque le permite controlar el comportamiento de ClassB sin tener que anidar objetos espías y evita cualquier posible problema que pueda surgir de esto.

Comments are closed.