superclase sirve referencia que para herencia ejemplos constructores comando clases java unit-testing mocking super powermock

java - sirve - Cómo burlarse de super referencia(en super clase)?



superclase java (3)

A veces, cuando escribo pruebas unitarias, debo burlarme de la referencia a la superclase.

He leído esta pregunta: pregunta

Esta respuesta responde con un consejo DI para refactorizar el código. Pero no puedo

esta respuesta, otra respuesta no es adecuada si el método de la superclase es lo suficientemente grande. En mi caso, tengo un código muy grande. Sí, sé que se trata de principios de SOLOD OOD, pero debo escribir una prueba. No tengo suficiente tiempo para refactor.

¡esa pregunta fue hecha hace 4 años!

¿Actualmente Mockito o Powermock pueden resolver este problema?

actualizar

ejemplo de código:

class BaseService { public void save() { // a lot of code here! I cannot change this code. } } public Childservice extends BaseService { public void save(){ //logic for testing super.save(); //logic for testing } }

actualización 2

public class Parent { public int save() { return 99; } } public class Child extends Parent { public int save() { int i = super.save(); return i*2; } }

y prueba:

@RunWith(PowerMockRunner.class) @PrepareForTest(Parent.class) public class ParentTest { @Test public void testSave() { PowerMockito.suppress(PowerMockito.methodsDeclaredIn(Parent.class)); System.out.println(new Child().save()); } }

salida: 198


Esto es imposible; el objetivo de una superclase es que encapsula el estado y la funcionalidad ascendentes, y la jerarquía de clases está codificada de forma rígida en su subclase según la relación de extends .


Con Powermock puede reemplazar o suprimir métodos, por lo que es posible cambiar la acción realizada por BaseService.save() . También puede hacer métodos para no hacer nada con la supresión. Incluso puede suprimir bloques de inicializadores estáticos.

Por favor, lea esta entrada de blog de los autores de Powermock . Ver el capítulo "Reemplazar".

ACTUALIZAR:

Suprimir parece funcionar para mí, pero no reemplace. Vea la imagen a continuación:


CON JMOCKIT

Lo he intentado con JMockit, y puede burlarse de la llamada al supermétodo. Por favor mira mi código:

public class Bar { public void bar() { System.out.println("Bar#bar()"); } } public class Foo extends Bar { public void bar() { super.bar(); System.out.println("Foo#bar()"); } } public final class MockBar extends MockUp<Bar> { private boolean barCalled = false; @Mock public void bar() { barCalled = true; System.out.println("mocked bar"); } public boolean isBarCalled() { return barCalled; } public void setBarCalled(boolean barCalled) { this.barCalled = barCalled; } } public class FooTest { @Test public void barShouldCallSuperBar() { MockBar mockBar = new MockBar(); Foo foo = new Foo(); foo.bar(); } }

Y el resultado en la consola es:

mocked bar Foo#bar()

CON MOCKITO Y POWERMOCKITO

public class Bar { public void bar() { System.out.println("Bar#bar()"); } public int numBar() { System.out.println("Bar#numBar()"); return 99; } } public class Foo extends Bar { public void bar() { super.bar(); System.out.println("Foo#bar()"); } public int numBar() { System.out.println("Foo#numBar() - before-call super.numBar()"); int result = super.numBar(); System.out.println("Foo#numBar() - after-call super.numBar();"); return result; } } @RunWith(PowerMockRunner.class) @PrepareForTest(Bar.class) public class FooTest { @Test public void testBar() throws Exception { Method method = PowerMockito.method(Bar.class, "bar"); PowerMockito.suppress(method); Foo foo = new Foo(); foo.bar(); } @Test public void testNumBar() throws Exception { Method methodFoo = PowerMockito.method(Foo.class, "numBar"); PowerMockito.replace(methodFoo).with(new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return 1; } }); Foo foo = new Foo(); int numBar = foo.numBar(); Assert.assertEquals(1, numBar); } }

Y el resultado de testNumber () es:

Foo#numBar() - before-call super.numBar() Foo#numBar() - after-call super.numBar();

Usted puede ver, no hay llamadas a la barra # numBar y el resultado esperado es 1.