2012-06-25 9 views
5

Es fácil verificar que se produjo una interacción específica (llamada de método específico) en un objeto simulado en Mockito, y existe verifyZeroInteractions() para comprobar que no se produjeron interacciones en absoluto. Supongamos que estoy probando una interfaz como la de un registrador, con métodos como info(), warn(), error() etc. En un escenario específico, sé que se debe llamar a uno de estos métodos, pero realmente no me importa cuál. ¿Existe alguna forma compacta de comprobar que se haya producido alguna interacción con el objeto simulado sin la necesidad de especificar qué método exactamente se debe invocar? ¿O quizás tal mecanismo no es necesario porque "la manera Mockito" de probar esto sería diferente de lo que imagino?¿Es posible verificar la interacción arbitraria usando Mockito de forma compacta?

Respuesta

1

Si puede externalizar la creación de su objeto logger de la clase bajo prueba, no hay ninguna razón por la cual no pueda escribir su propia implementación de prueba de la Interfaz de registro que registrará qué métodos se ejercitaron y lo inyectará como parte de su configuración de prueba.

Las bibliotecas de simulacros hacen mucho bien, pero a veces hay casos de esquina como los que ha encontrado donde pueden no cubrir sus necesidades.

Si usted escribe su propia aplicación para el ensayo de este tipo, y lo inyecta en yourt clase de prueba en prueba, entonces puede valer en getCount() > 0

public class LoggerTestSupportImpl implements ILogger { 

    private int count = 0; 

    @Override 
    public int getCount() { 
     return count; 
    } 

    @Override 
    public void info(String message) { 
     count++;  
    } 

    @Override 
    public void warn(String message) { 
     count++;  
    } 
} 
+1

Esto es exactamente lo que he estado probando mi clase hasta el momento, Me preguntaba si Mockito podría evitarme escribir las implementaciones triviales para todos los métodos. –

+0

Diría que has estado haciendo lo sensato Michal. Mockito no es compatible con este tipo de prueba. Su única opción es ir por la ruta 'ArgumentCaptor' como lo menciona Kevin, pero esto genera mucho" ruido "en las clases de prueba. – Brad

+0

De acuerdo, es un poco ruidoso, pero la mayoría del ruido se localiza en declaraciones y en el método Antes, e incluso se puede agregar el Captor a declaraciones de nivel de clase si se va a usar en varios métodos de prueba (ni siquiera es necesario si no se accede a mensajes) . Lo bueno de usar Mockito es que ya tienes acceso a la API de registro completo. Para hacerlo, en su ejemplo debe expandir las capacidades de su simulacro enrollado a mano (capturar/recuperar un número arbitrario de mensajes registrados, etc.). Pero para las necesidades simples su camino parece más simple, más limpio, * y * reutilizable, por lo que son algunas ventajas para su enfoque. –

2

Con log4j, para poner a prueba el registrador hago la siguiente configuración:

@Mock private Appender log4jAppender; 
private Logger logger; 

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 

    Logger root = Logger.getRootLogger(); 
    if (!root.getAllAppenders().hasMoreElements()) { 
     // No appenders means log4j is not initialized! 
     BasicConfigurator.configure(); 
    } 
    logger = Logger.getLogger(MyClassWhichLogs.class); 
    logger.addAppender(log4jAppender); 
} 

y luego en mi prueba hago lo siguiente:

verifyZeroInteractions(log4jAppender); 

o

verify(log4jAppender).doAppend(any(LoggingEvent.class); 

Si necesita probar los valores registrados, puede proporcionar un captor en su lugar:

ArgumentCaptor<LoggingEvent> logCaptor = ArgumentCaptor.forClass(LoggingEvent.class); 
verify(log4jAppender).doAppend(logCaptor.capture()); 
assertTrue(logCaptor.getValue().contains("my text to match"); 

Si bien esto no necesariamente responde a la pregunta generalizada (no creo que exista lo que está buscando), puede solucionar este problema específico para probar el registro.

Cuestiones relacionadas