2012-03-06 19 views
43

Tengo algunos métodos de utilidad estáticos en mi proyecto, algunos de ellos simplemente pasan o lanzan una excepción. Hay muchos ejemplos sobre cómo simular un método estático que tiene un tipo de devolución que no es nulo. Pero, ¿cómo puedo simular un método estático que devuelve vacío a solo "doNothing()"?¿Cómo me burlo de un método estático que devuelve vacío con PowerMock?

La versión no nula utiliza estas líneas de códigos:

@PrepareForTest(StaticResource.class) 

...

PowerMockito.mockStatic(StaticResource.class); 

...

Mockito.when(StaticResource.getResource("string")).thenReturn("string"); 

Sin embargo, si se aplica a un StaticResources que devuelve void, la compilación se quejará de que when(T) no es aplicable para el vacío ...

¿Alguna idea?

Una solución alternativa sería simplemente tener todos los métodos estáticos para devolver el resultado Boolean pero no me gustan las soluciones.

Respuesta

25

Puede hacerlo de la misma forma que lo hace con Mockito en instancias reales. Por ejemplo, puede talones de la cadena, la siguiente línea va a hacer la primera llamada no hacer nada, luego la segunda y futura llamada a getResources lanzará la excepción:

// the stub of the static method 
doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

// the use of the mocked static code 
StaticResource.getResource("string"); // do nothing 
StaticResource.getResource("string"); // throw Exception 

Gracias a una observación de Matt Lachman, tenga en cuenta que si el valor por defecto la respuesta no se cambia en el momento de la creación simulada, el simulacro no hará nada por defecto. Por lo tanto, escribir el siguiente código es equivalente a no escribirlo.

doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

Dicho esto, puede ser interesante para los colegas que leerán la prueba que no espera nada para este código en particular. Por supuesto, esto se puede adaptar en función de cómo se perciba comprensibilidad de la prueba.


Por cierto, en mi humilde opinión, debe evitar burlarse del código estático si crea un código nuevo. En Mockito creemos que, por lo general, es una pista para un mal diseño, puede llevar a un código que no se puede mantener. Aunque el código heredado existente es otra historia.

Hablando en general si necesita burlarse de un método privado o estático, este método hace demasiado y se debe externalizar en un objeto que se inyectará en el objeto probado.

Espero que ayude.

Saludos

+1

desgracia que no va a funcionar como cuando() sólo acepta una variable y StaticResource es un tipo. ('StaticResource no se puede resolver en una variable ') – Pete

+0

Oh, sí lo siento, tienes razón en que mi código está equivocado, estoy acostumbrado a los simulacros no estáticos. De todos modos, actualicé mi respuesta para reflejar la sintaxis correcta. – Brice

+0

¡Gracias! ¿Entonces tener métodos estáticos de ayuda que no tienen dependencias es una mala idea? Por supuesto que podría simplemente inyectar y objetar que hace el trabajo, pero parece que tiene sentido poner a los trabajadores que no tienen dependencias en un objeto estático para expresar su independencia. – Pete

55

Puede talón de un método vacío estático como sigue:

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString()); 

Aunque no estoy seguro de por qué se molestan, porque cuando se llama a mockStatic (StaticResource.clase) todos los métodos estáticos en StaticResource son por defecto apagó

más útil, que puede capturar el valor pasado a StaticResource.getResource() así:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 
PowerMockito.doNothing().when(
       StaticResource.class, "getResource", captor.capture()); 

A continuación, se puede evaluar la cadena que se pasó a StaticResource.getResource así:

String resourceName = captor.getValue(); 
+0

Ser capaz de hacer esto es muy bueno, ya que le permite hacer cosas como burlarse de Thread.sleep (millis largos) para dormir durante un tiempo diferente/menos tiempo/¡sin tiempo! – fragorl

+0

¿Hay alguna forma de evitar el uso de cadenas para los métodos, como "getResource" en tu ejemplo? –

8

En términos más simples, Imagínese si quieres maqueta debajo de la línea:

StaticClass.method(); 

continuación, se escribe debajo de las líneas de código para simulacro:

PowerMockito.mockStatic(StaticClass.class); 
PowerMockito.doNothing().when(StaticClass.class); 
StaticClass.method(); 
1

para burlarse de un método estático que vuelve vacía por ejemplo, Fileutils.forceMKdir(File file),

Código de ejemplo:

File file =PowerMockito.mock(File.class); 
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file); 
Cuestiones relacionadas