Leí algunos hilos aquí sobre métodos estáticos, y creo que entiendo los problemas que puede causar el mal uso / uso excesivo de métodos estáticos. Pero realmente no llegué al fondo de por qué es difícil burlarse de los métodos estáticos.
Sé que otros frameworks burlones, como PowerMock, pueden hacer eso, pero ¿por qué no Mockito?
Leí este artículo , pero el autor parece estar religiosamente en contra de la palabra static
, tal vez es mi pobre comprensión.
Una explicación / enlace fácil sería genial.
Respuestas:
Creo que la razón puede ser que las bibliotecas de objetos simulados suelen crear simulacros creando dinámicamente clases en tiempo de ejecución (usando cglib ). Esto significa que implementan una interfaz en tiempo de ejecución (eso es lo que hace EasyMock si no me equivoco) o heredan de la clase para burlarse (eso es lo que hace Mockito si no me equivoco). Ambos enfoques no funcionan para miembros estáticos, ya que no puede anularlos usando la herencia.
La única forma de burlarse de las estadísticas es modificar el código de bytes de una clase en tiempo de ejecución, lo que supongo que es un poco más complicado que la herencia.
Esa es mi suposición, por lo que vale ...
fuente
Si necesita burlarse de un método estático, es un fuerte indicador de un mal diseño. Por lo general, se burla de la dependencia de su clase bajo prueba. Si su clase bajo prueba se refiere a un método estático, como java.util.Math # sin, por ejemplo, significa que la clase bajo prueba necesita exactamente esta implementación (de precisión frente a velocidad, por ejemplo). Si quiere abstraerse de una implementación sinusal concreta, probablemente necesite una interfaz (¿ve a dónde va esto?)
fuente
En serio, creo que es olor a código si también necesitas burlarte de los métodos estáticos.
La única vez que esto me parece excesivo es libs como Guava, pero de todos modos no deberías necesitar burlarte de este tipo porque es parte de la lógica ... (cosas como Iterables.transform (..)) De
esa manera tu propio código se mantiene limpio, puede burlarse de todas sus dependencias de manera limpia y tiene una capa anticorrupción contra dependencias externas. He visto PowerMock en la práctica y todas las clases para las que lo necesitábamos estaban mal diseñadas. Además, la integración de PowerMock a veces causó serios problemas
(por ejemplo, https://code.google.com/p/powermock/issues/detail?id=355 )
PD: Lo mismo vale para los métodos privados, también. No creo que las pruebas deban conocer los detalles de los métodos privados. Si una clase es tan compleja que tienta a burlarse de métodos privados, probablemente sea una señal de dividir esa clase ...
fuente
@Inject SomeDependency
y en mi configuración que definobind(SomeDependency.class).in(Singleton.class)
. Por lo tanto, si mañana ya no es un Singleton, cambio la configuración y ya está.Foo.getInstance()
todas partes. Acabo de escribir singleton en la respuesta para contrarrestar el argumento "pero un método estático no requiere la creación de muchos objetos wrapper". También conceptualmente para mí hay poca diferencia entre un método estático y un método de instancia en un singleton, solo que no puedes burlarte de este colaborador singleton. Pero singleton o no no es absolutamente el punto que estaba tratando de hacer, el punto es inyectar y burlarse de los colaboradores y no llamar a métodos estáticos si dificulta las pruebas.Mockito devuelve objetos, pero static significa "nivel de clase, no nivel de objeto". Mockito dará una excepción de puntero nulo para static.
fuente
En algunos casos, los métodos estáticos pueden ser difíciles de probar, especialmente si necesitan ser burlados, razón por la cual la mayoría de los marcos de burla no son compatibles. Encontré que esta publicación de blog es muy útil para determinar cómo burlarse de los métodos y clases estáticos.
fuente