Estoy usando Mockito en algunas pruebas.
Tengo las siguientes clases:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
Quiero burlarme solo de la segunda llamada ( super.save
) de ChildService
. La primera llamada debe llamar al método real. ¿Hay una manera de hacer eso?
Respuestas:
No, Mockito no admite esto.
Puede que esta no sea la respuesta que está buscando, pero lo que está viendo es un síntoma de no aplicar el principio de diseño:
Si extrae una estrategia en lugar de extender una superclase, el problema desaparece.
Sin embargo, si no se le permite cambiar el código, pero debe probarlo de todos modos, y de esta manera incómoda, todavía hay esperanza. Con algunas herramientas AOP (por ejemplo, AspectJ) puedes tejer código en el método de superclase y evitar su ejecución por completo (puaj). Esto no funciona si está usando proxies, debe usar la modificación del código de bytes (ya sea tejido en tiempo de carga o tejido en tiempo de compilación). Hay marcos de burla que también admiten este tipo de trucos, como PowerMock y PowerMockito.
Te sugiero que optes por la refactorización, pero si esa no es una opción, te espera una gran diversión de piratería.
fuente
//some codes
código en un método que podría probarse por separado.Si realmente no tiene una opción para refactorizar, puede simular / eliminar todo en la llamada al súper método, por ejemplo
fuente
BaseService
es abstracto, aunque no veo por qué eso sería relevante.super.validate()
Considere refactorizar el código del método ChildService.save () a un método diferente y pruebe ese nuevo método en lugar de probar ChildService.save (), de esta manera evitará llamadas innecesarias al súper método.
Ejemplo:
fuente
cree un método protegido por paquete (asume la clase de prueba en el mismo paquete) en la subclase que llama al método de superclase y luego llame a ese método en su método de subclase anulado. Luego, puede establecer expectativas sobre este método en su prueba mediante el uso del patrón de espionaje. no es bonito, pero ciertamente es mejor que tener que lidiar con todas las expectativas establecidas para el súper método en su prueba
fuente
Incluso si estoy totalmente de acuerdo con la respuesta de iwein (
), admito que hay ocasiones en las que la herencia parece natural, y no siento que se rompa o refactorice solo por el bien de una prueba unitaria.
Entonces, mi sugerencia:
Y luego, en la prueba unitaria:
fuente
La razón es que su clase base no es public-ed, entonces Mockito no puede interceptarla debido a la visibilidad, si cambia la clase base como pública, o @Override en subclase (como pública), entonces Mockito puede burlarse de ella correctamente.
fuente
Tal vez la opción más fácil si la herencia tiene sentido es crear un nuevo método (paquete privado?) Para llamar al super (llamémoslo superFindall), espiar la instancia real y luego burlarse del método superFindAll () de la manera que deseaba simular la clase principal uno. No es la solución perfecta en términos de cobertura y visibilidad, pero debería funcionar y es fácil de aplicar.
fuente