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.

Mokito/Java – Falsificación de métodos estáticos

Por ejemplo, tengo las siguientes clases a continuación:

public class TesteEstatico {

   public static String teste(){
      return "FOO";
   }

}

Y tengo una clase que usa su método:

public class UsaTesteEstatico {

   public String metodoParaTeste1 (){
       return  TesteEstatico.teste() + " BAR ";
   }

   public String metodoParaTeste2 (){
       return  "FOO "+TesteEstatico.teste() + " BAR ";
   }

}

Clase de prueba:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; 
import org.mockito.InjectMocks; 
import org.mockito.Mockito; 
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class) public class UsaTesteEstaticoTest {

   @InjectMocks
   UsaTesteEstatico usaTesteEstatico;

   @Test
   void teste1(){
       Mockito.mockStatic(TesteEstatico.class);
       Mockito.when(TesteEstatico.teste())
            .thenReturn("BANANA");

       String res = usaTesteEstatico.metodoParaTeste1();
       System.out.println(res);
   }

   @Test
   void teste2(){
       Mockito.mockStatic(TesteEstatico.class);
       Mockito.when(TesteEstatico.teste())
            .thenReturn("LARANJA");

       String res = usaTesteEstatico.metodoParaTeste2();
       System.out.println(res);

   }
}

Error que obtengo al intentar ejecutar las pruebas:

org.mockito.exceptions.base.MockitoException: 
Para TesteEstatico, la simulación estática ya está registrada en el hilo actual
Para crear una nueva simulación, es necesario cancelar el registro de la simulación estática existente

Versiones de las bibliotecas que están en el proyecto:

  • junit-jupiter 5.5.2
  • mockito-junit-jupiter 3.2.14
  • mockito-inline 3.2.14

¿Alguna idea de cómo resolver esto? He intentado algunas cosas pero no tuve éxito.

NOTA: No puedo cambiar o agregar ninguna biblioteca nueva, ya que es un proyecto restringido.

Tags:  ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que ya hay un mock estático registrado para la clase TesteEstatico en el hilo actual. Esto puede ocurrir si varios métodos de prueba intentan hacer un mock de la misma clase al mismo tiempo.

    Una solución es utilizar las anotaciones @BeforeAll y @AfterAll para crear y eliminar el mock estático solo una vez, antes y después de que se ejecuten todos los métodos de prueba.

    Aquí tienes un ejemplo:

    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.AfterAll;
    import org.junit.jupiter.api.extension.ExtendWith; 
    import org.mockito.InjectMocks; 
    import org.mockito.Mockito; 
    import org.mockito.junit.jupiter.MockitoExtension;
    
    @ExtendWith(MockitoExtension.class)
    public class UsaTesteEstaticoTest {
    
       @InjectMocks
       UsaTesteEstatico usaTesteEstatico;
    
       @BeforeAll
       static void setUp() {
           Mockito.mockStatic(TesteEstatico.class);
       }
    
       @AfterAll
       static void tearDown() {
           Mockito.mockStatic(TesteEstatico.class).close();
       }
    
       @Test
       void teste1(){
           Mockito.when(TesteEstatico.teste())
                .thenReturn("BANANA");
    
           String res = usaTesteEstatico.metodoParaTeste1();
           System.out.println(res);
       }
    
       @Test
       void teste2(){
           Mockito.when(TesteEstatico.teste())
                .thenReturn("LARANJA");
    
           String res = usaTesteEstatico.metodoParaTeste2();
           System.out.println(res);
    
       }
    }
    

    En este ejemplo, el mock estático se crea en el método setUp(), el cual está anotado con @BeforeAll y se ejecuta solo una vez antes de cualquier método de prueba.

    El mock se elimina en el método tearDown(), el cual está anotado con @AfterAll y se ejecuta solo una vez después de que todos los métodos de prueba hayan terminado.

    Los métodos @Test pueden utilizar el método Mockito.when() para definir el comportamiento del método estático y el objeto usaTesteEstatico puede llamar a sus métodos como de costumbre.

    Ten en cuenta que también he cambiado el orden de las anotaciones, para que @ExtendWith esté en la parte superior y el nombre de la clase esté en la primera línea para una mejor legibilidad.

Comments are closed.