2012-08-23 14 views
12

Estoy usando Mockito para las pruebas de JUnit. por lo que hay una clase dada A que se utiliza a partir del código Quiero probar:Mockito: cuando se llama al método A.a, ejecuta B.b

class A{ 

    public A(){} 

    public final String a(String x){ 
     return "A.a: " + x; 
    } 

} 

y quiero reemplazar el A.a llamada al método con otra llamada al método con los mismos argumentos y el mismo tipo de valor de retorno. Como puede ver, no es posible anular el método a extendiendo la clase ya que es final. Así que lo que tenemos ahora es otra clase B con el método B.b:

class B{ 

    public B(){} 

    public String b(String x){ 
     return "B.b: " + x; 
    } 

} 

Ahora quiero para asegurarse de que cada vez que A.a se llama desde el código, el valor de retorno de B.b se utiliza en su lugar. ¿Existe la posibilidad de lograr esto con Mockito (algo así como Mockito.when(A.a(x)).thenReturn(B.b(x));) pero con el mismo parámetro x, sin saber el valor de x?

¡Cualquier ayuda sería apreciada, gracias de antemano!

+2

¿Cuál es el escenario que desea probar? ¿Por qué A.a() es final? y ¿Por qué quiere reemplazar la llamada de A.a()? Por lo que entiendo, quieres anular A.a(), ¿verdad? – Adelin

+1

Estoy probando un proyecto de biblioteca de Android (también uso Robolectric para poder probar proyectos de Android). En este caso particular, quiero probar una base de datos. El código llama a un solucionador de contenido, el proveedor de contenido está definido en AndroidManifest.xml y no he encontrado una manera de configurar el proveedor de contenido mediante programación, ya que no se carga desde el xml al ejecutar las pruebas. Así que quería que el código llamara al proveedor de contenido en lugar de a la resolución de contenido. – user1448982

Respuesta

4

No es posible anular los métodos finales para los simulacros generados por Mockito, de acuerdo con Mockito limits. Pero puede usar Powermock para hackear código en tiempo de ejecución para que Mockito pueda hacer su trabajo.

+2

Esto soluciona el problema 'final' y la respuesta de @brice responde a la esencia de su pregunta original. – jhericks

18

El burlarse del mockito funciona ampliando la clase y anulando el método, que en su caso no es posible en A.a(String). Si quieres que esto suceda, debes eliminar el modificador final.

Ahora suponiendo A.a(String) no es definitiva, lo que se pide es completamente factible con Mockito:

given(mockA.a(anyString()).willAnswer(returnOfB(bInstance)); 

Answer<String> returnOfB(final B bInstance) { 
    return new Answer<String>() { 
     public String answer(Invocation invocation) { 
      String arg = (String) invocation.getActualArguments()[0]; 
      return bInstance.b(arg); 
     } 
    }; 
} 

Tenga en cuenta que esta respuesta ha sido escrito en un teléfono y podría tener error tipográfico, o nombres equivocados, aunque usted debe conseguir la idea de qué se debe hacer para lograr lo que quieres.

Saludos

+0

gracias, pero no es una solución para mí, ya que no puedo eliminar el modificador final. Es un código del SDK de Android. – user1448982

+3

@sergej-zagursky tiene la respuesta para evitar el problema del modificador final, pero este responde la esencia de su pregunta original. Así es como usted basa su valor de retorno en el valor de 'x'. – jhericks

+0

¿Cómo importo el "dado"? – neves

1

Básicamente tomaron su configuración y escribieron una unidad de prueba con él. Lo primero que apareció fue un mensaje de error que explícitamente decía esto:

org.mockito.exceptions.misusing.MissingMethodInvocationException: cuando() requiere un argumento que tiene que ser 'una llamada a un método en un simulacro'.

Y más tarde en la traza se establece que "usted tropieza cualquiera de:./Final métodos privados/equals()/hashCode() Estos métodos no pueden se apagó/verificados."

De acuerdo con Mockito no se pueden trozar los métodos finales, y eso es todo.

Editar: Por lo tanto, debe eliminar el modificador final o, en caso de que esté atascado con esta clase tal como está, busque otra forma de evitarlo.

Cuestiones relacionadas