Вопрос

Что у меня есть сейчас

У меня есть экземпляр синглтона стороннего производителя, на который опирается мой тестируемый класс, и этот синглтон использует 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"));
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top