Ответ 1
Возможно, вы ищете макет политики?
Я использую PowerMock для моделирования статических методов в тестах junit, как правило, следующим образом:
@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() {
...
}
}
Это отлично работает, но я считаю, что указание аннотации @PrepareForTest
мешает мне сделать гибкий API для тестирования.
Что я хотел бы сделать, это примерно следующее:
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() {
...
}
}
Здесь my unit test имеет зависимость от LibraryOne
, но не знает, от каких классов LibraryOne
зависит, поэтому он не знает, какие классы добавить в аннотацию @PrepareForTest
.
Я мог бы сделать SomeUnitTest
extend MockLibraryOne
и добавить аннотацию @PrepareForTest
к классу MockLibraryOne
, но в других модульных тестах я буду иметь зависимости больше, чем просто MockLibraryOne
, поэтому наследование не является общим решение.
Есть ли какой-то способ программной подготовки класса для тестирования в PowerMock вместо использования аннотации @PrepareForTest
? Например, что-то вроде следующего:
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);
}
}
Я думаю, было бы неплохо, если бы PowerMockRunner
обработало аннотацию @PrepareForTest
несколько иначе: для каждого указанного класса он должен не только добавить этот класс (и его иерархию) в список классов для подготовки к издевательствам, но затем изучите этот класс, чтобы увидеть, есть ли в нем аннотации @PrepareForTest
:
@RunWith(PowerMockRunner.class)
@PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
@PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
Итак, в этом аннотация @PrepareForTest
на SomeUnitTest
найдет MockLibraryOne
, а аннотация @PrepareForTest
будет таскать в Foo.class
и Bar.class
.
Поэтому, возможно, написать мой собственный тестовый бегун для замены PowerMockRunner
может быть решением.
Или, может быть, есть более простое решение, используя класс PowerMockAgent
, например?
edit: Mock Policies может быть одним из решений: https://code.google.com/p/powermock/wiki/MockPolicies
edit: Mock Policies работает с PowerMockRunner
, но не (кажется) с PowerMockRule
(что я иногда требую из-за проблем загрузчика класса).
Возможно, вы ищете макет политики?
Почему вы даже хотите издеваться над статическими методами? Почему бы не обернуть эти статические методы в классе, который вы можете высмеивать с помощью mockito?
class FooWraper {
void someMethod() {
Foo.someStaticMethod()
}
}
а затем вы можете создать макет вашего FooWraper. Нет необходимости использовать Powermock вообще...