Класс Mock System для получения свойств системы

У меня есть путь к папке, установленный в системной переменной через аргументы JVM в Eclipse, и я пытаюсь получить к нему доступ в моем классе: System.getProperty("my_files_path").

При написании метода тестирования junit для этого класса я попытался издеваться над этим вызовом, поскольку тестовые классы не учитывают аргументы JVM. Я использовал PowerMockito для издевательства статического класса System и попытался вернуть некоторый путь при вызове System.getProperpty.

Были аннотации @RunWith(PowerMockRunner.class) и @PrepareForTest(System.class) на уровне класса. Тем не менее, System class не получает издевательства, в результате я всегда получаю нулевой результат.  Любая помощь приветствуется.

Ответ 1

Спасибо, Сатиш. Это работает, за исключением небольшой модификации. Я написал PrepareForTest (PathFinder.class), готовя класс, который я тестирую для тестовых примеров, вместо System.class

Кроме того, поскольку макет работает только один раз, я вызвал свой метод сразу после насмешки. Мой код для справки:

@RunWith(PowerMockRunner.class)
@PrepareForTest(PathInformation.class)
public class PathInformationTest {

    private PathFinder pathFinder = new PathFinder();

@Test
    public void testValidHTMLFilePath() { 
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getProperty("my_files_path")).thenReturn("abc");
        assertEquals("abc",pathFinder.getHtmlFolderPath());
    }
}

Ответ 2

Есть определенные классы, которые PowerMock не может издеваться обычным способом. Посмотреть здесь:

Это, однако, может все еще не работать. В порядке предпочтения "хороший дизайн" вы можете воспользоваться следующими:

  1. Рефакторинг вашего кода! Использование свойства System для передачи пути к файлу, вероятно, не лучший способ. Почему бы не использовать файл свойств, загруженный в объект Properties? Почему бы не использовать геттеры/сеттеры для компонентов, которым необходимо знать этот путь? Есть много лучших способов сделать это.

    Единственная причина, по которой я мог подумать не делать этого, это то, что вы пытаетесь обернуть тестовый набор кода, который вы "не можете" изменить.

  2. Используйте @Before и @After чтобы установить для свойства System некоторое известное значение для теста (ов). Вы даже можете сделать это частью самого метода @Test. Это будет намного проще, чем пытаться издеваться над PowerMock. Просто вызовите System.setProperty("my_files_path","fake_path");

Ответ 3

Задайте системное свойство в своем тесте и убедитесь, что оно восстанавливается после теста, используя правило RestoreSystemProperties библиотеки System Rules.

public class PathInformationTest {
  private PathFinder pathFinder = new PathFinder();

  @Rule
  public TestRule restoreSystemProperties = new RestoreSystemProperties();

  @Test
  public void testValidHTMLFilePath() { 
    System.setProperty("my_files_path", "abc");
    assertEquals("abc",pathFinder.getHtmlFolderPath());
  }
}

Ответ 4

Системный класс объявлен как окончательный и не может быть смоделирован библиотеками, такими как PowerMock. Несколько ответов, опубликованных здесь, неверны. Если вы используете Apache System Utils, вы можете использовать метод getEnvironmentVariable вместо прямого вызова System.getenv. SystemUtils может быть поддельным, поскольку он не объявлен как окончательный.

Ответ 5

@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
public class MySuperClassTest {   
@Test
public void test(){ 
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getProperty("java.home")).thenReturn("abc");
    System.out.println(System.getProperty("java.home"));
}
} 

Ответ 6

Sailaja добавляет System.class, потому что в соответствии с руководящими принципами макета для статического, частного издевательства вы должны добавить класс в подготовку к тестированию.

 @PrepareForTest({PathInformation.class,System.class})

Надеюсь, что это поможет. Скажите мне, если это не работает.