Как использовать System.getenv в Junit PowerMockito

Я могу смоделировать значение System.getenv из Junit, но когда я выполняю тестовый пример - в моем классе обслуживания значение System.getevn, равное нулю. Не уверен, что я здесь делаю не так. Пожалуйста, найдите мой тестовый класс обслуживания и класс Junit.

Могут ли некоторые помочь мне решить эту проблему - почему значение не устанавливается в моем классе обслуживания?

TestService.java

public class TestService {

    public TestService() throws Exception {

        loadTestMethod();

    }

    private void loadTestMethod() {

        System.out.println("Environment vairlable : " + System.getenv("my_key_name"));
        System.setProperty("app.key", System.getenv("my_key_name"));

    }

}

TestServiceTest.java

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(value = { System.class })
@PowerMockIgnore("javax.management.*")

public class TestServiceTest {

    @Mock
    TestService testService;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getenv("my_key_name")).thenReturn("Testing");
        System.out.println("Junit Environment vairlable : " + System.getenv("my_key_name"));
        testService = new TestService();

    }

    @Test
    public void myServiceTest() {

    }
}

1 ответ

Тот факт, что PowerMockito позволяет нам издеваться над статичными, не означает, что мы должны это делать.

Ваши классы зависят от статических проблем реализации, которые делают изолированное модульное тестирование в большинстве случаев трудным.

Рассмотрите возможность следования Explicit Dependency Principle

Методы и классы должны явно требовать (обычно через параметры метода или параметры конструктора) любых взаимодействующих объектов, в которых они нуждаются для правильного функционирования.

Создать абстракцию желаемой функциональности

public interface SystemWrapper {
    //The "standard" output stream
    PrintStream out;
    //Gets the value of the specified environment variable
    string getenv(string name);
    //Sets the system property indicated by the specified key.
    string setProperty(String key, String value);
}

Реализация будет инкапсулировать фактические вызовы в статический системный класс

public class SystemWrapperImplementation implements SystemWrapper {
    //The "standard" output stream
    public final PrintStream out = System.out;

    //Gets the value of the specified environment variable
    public string getenv(string name) {
        return System.getenv(name);
    }

    //Sets the system property indicated by the specified key.
    public string setProperty(String key, String value) {
        return System.setProperty(key, value);
    }
}

Ваш зависимый класс должен быть подвергнут рефакторингу для включения абстракции

public class TestService {
    private SystemWrapper system;

    public TestService(SystemWrapper system) throws Exception {
        this.system = system;
        string key = "app.key";
        string name = "my_key_name";
        loadTestMethod(key, name);
    }

    private void loadTestMethod(string key, string name) {
        string environmentVariable = system.getenv(name);
        system.out.println("Environment variable : " + environmentVariable);
        system.setProperty(key, environmentVariable);
    }
}

Теперь для тестирования вы можете смоделировать необходимые зависимости по мере необходимости без каких-либо побочных эффектов. Реализация будет затем использоваться в производстве при вызове фактического кода.

Наконец, я бы предложил, чтобы ваши конструкторы не генерировали исключения. Конструкторы должны в основном использоваться для присваивания переменных.

Другие вопросы по тегам