Тестирование кода, который вызывает собственные методы
У меня есть класс вроде этого:
public final class Foo
{
public native int getBar();
public String toString()
{
return "Bar: " + getBar();
}
}
Обратите внимание, что getBar() реализуется с JNI и что класс является окончательным. Я хочу написать тест junit для тестирования метода toString(). Для этого мне нужно высмеять метод getBar(), а затем запустить исходный метод toString() для проверки вывода.
Моя первая мысль заключалась в том, что это должно быть невозможно, но затем я нашел PowerMock, который поддерживает тестирование финальных классов и собственных методов в соответствии с функцией список. Но пока у меня не было успеха. Лучшее, что мне удалось, это насмехаться над полным классом, но затем тест протестировал смеющийся метод toString() вместо реального, который не имеет большого смысла.
Итак, как я могу использовать PowerMock для тестирования этого метода toString() сверху? Я предпочитаю использовать PowerMock с Mockito, но если это невозможно, у меня нет проблем с использованием EasyMock.
Ответы
Ответ 1
Нашел. То, как я это делал, было правильным. Единственное, что я пропустил, было то, что макет вызывал оригинальный метод при вызове toString(). Поэтому он работает следующим образом:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Foo.class })
public class FooTest
{
@Test
public void testToString() throws Exception
{
Foo foo = mock(Foo.class);
when(foo.getBar()).thenReturn(42);
when(foo.toString()).thenCallRealMethod();
assertEquals("Bar: 42", foo.toString());
}
}
Ответ 2
Или используйте JMockit с динамическим частичным издевательством:
import org.junit.*;
import mockit.*;
public class FooTest
{
@Test
public void testToString()
{
final Foo foo = new Foo();
new Expectations(foo) {{ foo.getBar(); result = 42; }};
assertEquals("Bar: 42", foo.toString());
}
}
Ответ 3
Или используйте Шаблон стратегии:
public final class Foo
{
public IBarStrategy barStrategy;
......
}
interface IBarStrategy{
int getBar();
}
Когда unit test, введите экземпляр mock IBarStrategy
, затем вы можете проверить класс Foo
.