method unit-testing junit powermock

unit testing - method - ¿Reemplazando programáticamente el @PrepareForTest de PowerMock?



powermock static method (2)

Estoy usando PowerMock para simular métodos estáticos en las pruebas de junit, que normalmente se realiza de la siguiente manera:

@RunWith(PowerMockRunner.class) @PrepareForTest({Foo.class,Bar.class}) public class SomeUnitTest { @Before public void setUpTest() { setUpFoo(); setUpBar(); } private void setUpFoo() { mockStatic(Foo.class); when(Foo.someStaticMethod()).thenReturn(1); } private void setUpBar() { mockStatic(Bar.class); when(Bar.someStaticMethod()).thenReturn(2); } @Test public void someTestCase() { ... } }

Esto funciona bien, pero me @PrepareForTest que la especificación de la anotación @PrepareForTest impide que mi API de pruebas sea flexible.

Lo que me gustaría hacer es algo como lo siguiente:

public class MockLibraryOne { public static void setUpLibraryOne() { setUpFoo(); setUpBar(); } private static void setUpFoo() { mockStatic(Foo.class); when(Foo.someStaticMethod()).thenReturn(1); } private static void setUpBar() { mockStatic(Bar.class); when(Bar.someStaticMethod()).thenReturn(2); } } @RunWith(PowerMockRunner.class) public class SomeUnitTest { @Before public void setUpTest() { MockLibraryOne.setUpLibraryOne(); } @Test public void someTestCase() { ... } }

Aquí mi prueba de unidad depende de LibraryOne , pero no sabe de qué clases depende LibraryOne , por lo que no sabe qué clases agregar a la anotación @PrepareForTest .

Podría hacer que SomeUnitTest extienda MockLibraryOne y agregue la anotación @PrepareForTest a la clase MockLibraryOne , pero tendré dependencias en más que solo MockLibraryOne en otras pruebas de unidad, por lo que la herencia no es una solución general.

¿Hay alguna forma de preparar mediante programación una clase para realizar pruebas en PowerMock, en lugar de usar la anotación @PrepareForTest ? Por ejemplo, algo como lo siguiente:

public class MockLibraryOne { public static void setUpLibraryOne() { setUpFoo(); setUpBar(); } private static void setUpFoo() { prepareForTest(Foo.class); mockStatic(Foo.class); when(Foo.someStaticMethod()).thenReturn(1); } private static void setUpBar() { prepareForTest(Bar.class); mockStatic(Bar.class); when(Bar.someStaticMethod()).thenReturn(2); } }

Supongo que sería bueno si PowerMockRunner procesara la anotación @PrepareForTest un poco diferente: para cada clase especificada, no solo debería agregar esa clase (y su jerarquía) a la lista de clases para prepararse para el simulacro, sino que luego examinar esa clase para ver si tiene alguna anotación @PrepareForTest también:

@RunWith(PowerMockRunner.class) @PrepareForTest({MockLibraryOne.class}) public class SomeUnitTest { ... } @PrepareForTest({Foo.class,Bar.class}) public class MockLibraryOne { ... }

}

Entonces, en esta anotación de SomeUnitTest en SomeUnitTest se encontraría MockLibraryOne , y la anotación de @PrepareForTest se arrastraría también en Foo.class y Bar.class también.

Entonces tal vez escribir mi propio corredor de prueba para reemplazar PowerMockRunner puede ser una solución.

¿O tal vez hay una solución más simple, usando la clase PowerMockAgent , por ejemplo?

edición: las Políticas simuladas pueden ser una solución: https://code.google.com/p/powermock/wiki/MockPolicies

edición: Políticas simuladas funciona con PowerMockRunner pero no (parece) con PowerMockRule (que a veces necesito debido a problemas con el cargador de clases).


¿Por qué incluso quieres burlarte de los métodos estáticos? ¿Por qué no envolver esos métodos estáticos en una clase de la que puedes burlarte con mockito?

class FooWraper { void someMethod() { Foo.someStaticMethod() } }

y luego puedes crear un simulacro de tu FooWraper. No hay necesidad de usar Powermock en absoluto ...