Прежде всего, знайте, что я искал SO, прежде чем задавать этот вопрос, но не смог найти удовлетворительного ответа.
Я использую JUnit4 и Powermock 1.5.5 (с mockito 1.9.5)
Моя проблема заключается в следующем: в моих модульных тестах мне нужно смоделировать статический метод в классе, который я не могу изменить. Я хочу издеваться только над одним методом, а не над всем классом, поэтому я пошел на шпиона.
Вот что у меня есть до сих пор:
[...]
import static org.mockito.Matchers.*;
import static org.powermock.api.mockito.PowerMockito.*;
@RunWith(JUnitParamsRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext-test.xml"},
loader=MockWebApplicationContextLoader.class)
@MockWebApplication(name="my-app")
@PrepareForTest(value = {
Role.class
})
public class MyTest {
@Rule
public PowerMockRule powerMockRule = new PowerMockRule();
@Before
public void setUp() throws Exception {
initSpring();
mockRoleServices();
}
private void mockRoleServices() throws Exception {
spy(Role.class);
RoleAnswer roleAnswer = new RoleAnswer(RoleEnum.ADMIN);
when(Role.hasAdministratorRole(anyLong(), anyLong(), anyLong()))
.then(roleAnswer);
}
private class RoleAnswer implements Answer<Boolean> {
private RoleEnum roleEnum;
private RoleAnswer(RoleEnum roleEnum) {
this.roleEnum = roleEnum;
}
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
return getRenderRequest().getUserRole() != null &&
getRenderRequest().getUserRole().equals(roleEnum);
}
}
}
Вот в чем проблема: метод Role.hasAdministratorRole()
вызывается вместо того, чтобы над ним издеваться
Вот что я пробовал до сих пор:
- Использование
mockStatic(Role.class)
вместо методаspy()
. Как и ожидалось, все методы имитируются, поэтому я получаю NPE до вызоваRole.hasAdministratorRole()
- Делая что-то вроде
doAnswer(...).when(...)
. Я получаю ошибку времени выполнения, когда powermock сообщает мне, что мой макет не завершен (что на самом деле подтверждает, что что-то не так либо с моим кодом, либо с самой библиотекой) - Попытка объявить метод по его имени, а не вызывать его напрямую:
when(Role.class, "hasAdministratorRole", long.class, long.class, long.class)
. То же поведение - Куча других вещей, которые я уже не помню.
Ваша помощь будет принята с благодарностью. Спасибо !
EDIT: благодаря ответу SrikanthLingala я смог точно определить проблему.
Это не сработало:
when(Role.hasAdministratorRole(anyLong(), anyLong(), anyLong()))
.thenAnswer(roleAnswer);
но это сделало:
doAnswer(roleAnswer).when(Role.class, "hasSiteAdministratorRole",
anyLong(), anyLong(), anyLong());
Итак, переключение между when()
и answer()
сработало.