variable usar sirve restricción que para métodos metodos metodo estáticos estaticos cuando clase atributos java android static-methods mockito helpermethods

sirve - ¿Por qué es malo usar métodos de ayuda estática en Java?



restricción de java al usar atributos y métodos estáticos. (4)

El problema con los métodos estáticos es que son muy difíciles de falsificar cuando no son relevantes para el sistema que intentas probar. Imagina este código:

public void systemUnderTest() { Log.connectToDatabaseForAuditing(); doLogicYouWantToTest(); }

El método connectToDatabaseForAuditing() es estático. No te importa lo que este método hace para la prueba que quieres escribir. Pero, para probar este código ahora necesita una base de datos disponible.

Si no fuera estático, el código se vería así:

private Logger log; //instantiate in a setter AKA dependency injection/inversion of control public void systemUnderTest() { log.connectToDatabaseForAuditing(); doLogicYouWantToTest(); }

Y su prueba sería trivial para escribir sin una base de datos ahora:

@Before public void setUp() { YourClass yourClass = new YourClass(); yourClass.setLog(new NoOpLogger()); } //.. your tests

Imagínese tratando de hacer eso cuando el método es estático. Realmente no puedo pensar en una manera, excepto en modificar el registrador para que tenga una variable estática llamada inTestMode que configuraste en verdadero en el setUp() para asegurarte de que no se conecte a una base de datos.

Lo pregunto porque estoy tratando de usar un marco burlón (Mockito) que no te permite simular métodos estáticos. Al analizarlo, he encontrado bastantes publicaciones de blogs que dicen que deberías tener la menor cantidad de métodos estáticos posibles, pero tengo dificultades para entender por qué. Específicamente por qué los métodos que no modifican el estado global y son básicamente métodos auxiliares. Por ejemplo, tengo una clase llamada ApiCaller que tiene varios métodos estáticos. Uno de los propósitos del método estático es ejecutar una llamada HTTP, lidiar con cualquier problema personalizado que nuestro servidor pueda haber devuelto (por ejemplo, el usuario no ha iniciado sesión) y devolver la respuesta. Para simplificar, algo como:

public class ApiCaller { ... public static String makeHttpCall(Url url) { // Performs logic to retrieve response and deal with custom server errors ... return response; } }

Para usar esto, todo lo que tengo que hacer es llamar a ApiCaller.makeHttpCall(url) Ahora, fácilmente podría hacer de este un método no estático como:

public class ApiCaller { ... public String makeHttpCall(Url url) { // Performs logic to retrieve response and deal with custom server errors ... return response; } }

y luego, para usar este método, llame al new ApiCaller().makeHttpCall() pero esto parece una sobrecarga adicional. ¿Alguien puede explicar por qué esto es malo y si hay una mejor solución para hacer que los métodos no sean estáticos (aparte de simplemente eliminar la palabra clave) para que pueda eliminar estos métodos utilizando el marco de burla?

¡Gracias!


Es menos modular. En su lugar, debe definir una interfaz ApiCaller con un método de instancia makeHttpCall() para que pueda definir implementaciones separadas en el futuro.

Como mínimo, siempre tendrá 2 implementaciones de una interfaz, la versión original y la versión simulada.

(Nota: hay algunos marcos burlones que te permiten simular métodos estáticos)

Como anexo, si bien este puede no ser el caso en su aplicación específica, el uso de métodos estáticos generalmente es indicativo de una supervisión de diseño más amplia. El diseño para modularidad y reutilización debe prevalecer en toda la aplicación, ya que aunque no lo necesite en este momento, es posible que lo necesite en el futuro, y es mucho más difícil y más lento cambiar las cosas después del hecho.


PRIVADO Los métodos de ayuda estática no son malos, de hecho, en realidad son los preferidos en la gran corporación donde trabajo. Y uso Mockito con ellos todo el tiempo, al que se accede desde los métodos que llaman el método de ayuda estática.

Hay una ligera diferencia en cómo el compilador trata un método auxiliar estático. El código de byte creado resultará en una instrucción invokestatic , y si elimina la estática, el resultado será una de las otras instrucciones, como invocar especial. La diferencia es que invokestatic carga la clase para acceder al método, donde invoca especialmente el objeto de la pila. Así que puede haber una ligera ventaja de rendimiento (tal vez no).


Que no puedes burlarte de ellos fácilmente cuando necesitas responder prácticamente tu propia pregunta.

Particularmente cuando es algo como se muestra: hacer una llamada HTTP es costoso, y hacer eso para probar la unidad de su código no tiene sentido, guárdelo para las pruebas de integración.

Las pruebas unitarias requieren respuestas conocidas (y códigos de respuesta) de las llamadas HTTP, algo que no puede hacer si está llamando al servicio de otra persona , utilizando una red que no controla.