Как сделать JMockIt System.getenv (String)?
-
06-07-2019 - |
Вопрос
Что у меня есть сейчас
У меня есть экземпляр синглтона стороннего производителя, на который опирается мой тестируемый класс, и этот синглтон использует System.getenv (String)
в своем конструкторе. Можно ли издеваться над этим звонком?
Я пробовал это
Пример JMockIt
new Expectations()
{
System mockedSystem;
{
System.getenv( "FISSK_CONFIG_HOME" ); returns( "." );
}
};
Но он дает мне EXCEPTION_ACCESS_VIOLATION
и приводит к аварийному завершению JVM.
Есть ли другой способ установить системную переменную среды для модульного теста?
Решение
В этом случае вам нужно использовать частичное моделирование, чтобы JMockit не переопределял все в классе System. Следующий тест пройдет:
@Test
public void mockSystemGetenvMethod()
{
new Expectations()
{
@Mocked("getenv") System mockedSystem;
{
System.getenv("envVar"); returns(".");
}
};
assertEquals(".", System.getenv("envVar"));
}
Вскоре я реализую усовершенствование, чтобы подобные проблемы не возникали при издевательстве над классами JRE. Он должен быть доступен в версии 0.992 или 0.993.
Другие советы
PowerMock швы, чтобы можно было имитировать системные классы.
Другой вариант (при условии, что вы не проводите модульное тестирование сторонних API) - это создать для фасад сторонний API, который имеет приятный и легко поддающийся моделированию интерфейс, и ваши тестовые классы используют его, а не реальную вещь.
О, JMockIt это тоже поддерживает: тестовый пакет;
import static org.junit.Assert.*;
import mockit.*;
import mockit.integration.junit4.JMockit;
import org.junit.*;
import org.junit.runner.RunWith;
@RunWith(JMockit.class)
public class JMockItTest {
@Test
public void mockSystemGetEnv() {
Mockit.setUpMocks(MockSystem.class);
assertEquals("Bye", System.getenv("Hello"));
}
@MockClass(realClass = System.class)
public static class MockSystem {
@Mock
public static String getenv(String str) {
return "Bye";
}
}
}
Вы не можете изменить среду, но вы можете изменить доступ к ней: просто оберните вызов System.getenv ()
в метод или вспомогательный класс, а затем смоделируйте это. р>
[РЕДАКТИРОВАТЬ] Теперь ваша проблема заключается в том, как изменить код вашей сторонней библиотеки. Решением здесь является использование декомпилятора Java и исправление класса. Если вы хотите, вы можете отправить запрос на функцию в тоже. Добавьте этот новый класс в ваш набор тестов. Это должно заставить вашу IDE найти класс для тестов.
Поскольку тестовый код не запускается, вы можете запустить свои тесты, и рабочий код будет использовать оригинальную библиотеку.
Некоторое время назад я хотел протестировать System.exit , и нашел решение, используя пользовательский SecurityManager . Вы можете убедиться в том, что выполняется вызов, и в качестве аргумента вызова, но, используя этот метод, вы не можете высмеять возвращаемое значение вызова. Р>
Обновленная информация о @ Rog & # 233; rio answer.
В моем случае с JMockit 1.25 я должен был сделать это с помощью MockUp API:
@Test
public void mockSystemGetenvMethod(){
new MockUp<System>()
{
@Mock
public String getenv(final String string) {
return "";
}
};
assertEquals(".", System.getenv("envVar"));
}