2012-04-26 9 views
6

Estoy queriendo usar dos emparejamientos personalizados para un solo método. Básicamente, si paso el método VALOR_A, quiero que devuelva RESULT_A, y si lo paso a VALUE_B, quiero que devuelva RESULT_B. Así que aquí está un extracto de código:Mockito actúa de manera extraña cuando asigno múltiples emparejamientos personalizados a un solo método

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher to MockHtable.get() 
     //When this happens, the value of the get argument is null, so this method throws an NPE 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

class IsEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     return !(Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key))); 
    } 
}  

[...] 

//This line executes just fine 
Mockito.when(mockHTable.get(Mockito.argThat(new IsNonEmpty()))).thenReturn(dbResult); 

[...] 

//This line calls IsNonEmpty.matches() for some reason. IsNonEmpty.matches() throws an NPE 
Mockito.when(mockHTable.get(Mockito.argThat(new IsEmpty()))).thenReturn(emptyResult); 

Cuando le asigno el encargo de coincidencias IsEmpty al método mockHTable.get(), llama a la función IsNonEmpty.matches(). No tengo idea de por qué está haciendo esto. Así que cambio la clase IsNonEmpty a esto:

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher. Weird, no? 
     if(get == null) { 
      return false; 
     } 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

y luego todo funciona bien! IsNonEmpty.matches() todavía se invoca cuando asigno el emparejador IsEmpty a la función mockHTable.get(), pero mis emparejamientos funcionan exactamente como deberían.

¿Cuál es el problema? ¿Por qué pasó esto? ¿Es mi forma de trabajo una forma adecuada de compensar este comportamiento peculiar, o lo estoy haciendo mal?

Respuesta

11

El motivo por el cual se llama a IsNonEmpty.matches() en la segunda línea de muestreo es que Mockito.argThat(new IsEmpty()) devuelve nulo, que luego se pasa al mockHTable.get(). Esta llamada debe verificarse con el trozo anterior para ver si coincide; y eso significa llamar al IsNonEmpty.matches().

No estoy seguro de por qué esto hace que su prueba falle - es difícil de decir sin ver todo el código.

Pero, seriamente recomendaría usar doReturn...when en lugar de when...thenReturn cada vez que tenga que colgarse el mismo simulacro más de una vez. No encontrarás problemas como este si lo haces. De hecho, prefiero usar doReturn...when con preferencia a when...thenReturn siempre (y de manera similar doThrow y doAnswer), aunque la mayoría de la gente prefiere when...thenReturn.

Reescribiendo una de sus líneas de stubbing con la sintaxis doReturn...when tiene el siguiente aspecto. El otro es similar

Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty())); 

Por último, una declaración, en nombre del equipo de desarrollo Mockito (de la que soy miembro). Si le parece que es un error en Mockito aquí - y de su descripción, creo que es muy posible que - por favor SEA

  • enviar un mensaje al grupo de correo Mockito ([email protected]) O
  • plantear un problema en la lista de problemas de Mockito (http://code.google.com/p/mockito/issues/list).

Es útil para el equipo Mockito si en realidad se puede poner un ejemplo completo, en lugar de lo que usted piensa las líneas principales son - a veces la causa de un problema Mockito está en un lugar bastante inesperado.

Cuestiones relacionadas