이 스레드를 찾은 대부분의 사람들과 마찬가지로, 몇 가지 단위 테스트를 작성했으며 테스트를 실행하기위한 올바른 조건을 설정하기 위해 환경 변수를 수정해야했습니다. 그러나 가장 많이 찬성 된 답변에 몇 가지 문제가 있거나 매우 복잡하거나 지나치게 복잡하다는 것을 알았습니다. 잘하면 이것이 다른 사람들이 솔루션을 더 빨리 분류하는 데 도움이되기를 바랍니다.
먼저 @Hubert Grzeskowiak의 솔루션이 가장 간단하다는 것을 알았습니다. 나는 그 중 하나에 먼저 왔으면 좋겠다. @Edward Campbell의 답변을 기반으로하지만 루프 검색이 복잡하지 않습니다.
그러나 @pushy의 솔루션으로 시작했는데 가장 많은 찬사를 받았습니다. @anonymous와 @Edward Campbell의 조합입니다. @pushy는 Linux와 Windows 환경을 모두 다루기 위해 두 가지 접근 방식이 모두 필요하다고 주장한다 OS X에서 실행 중이며 두 가지 모두 작동합니다 (@anonymous 접근 방식의 문제가 해결 된 경우). 다른 사람들이 지적 했듯이이 솔루션은 대부분 작동하지만 전부는 아닙니다.
혼란의 원인은 '환경'필드에서 작동하는 @anonymous의 솔루션에서 비롯된 것 같습니다. ProcessEnvironment 구조 의 정의를 보면 'TheEnvironment'는 Map <String, String>이 아니라 Map <Variable, Value>입니다. 맵을 지우면 정상적으로 작동하지만 putAll 조작은 Map <String, String> 맵을 다시 빌드하므로 Map <Variable, Value>를 예상하는 일반 API를 사용하여 데이터 구조에서 후속 조작이 조작 될 때 잠재적으로 문제점이 발생합니다. 또한 개별 요소에 액세스 / 제거하는 것이 문제입니다. 해결책은 '수정 불가능한 환경'을 통해 '환경'에 간접적으로 액세스하는 것입니다. 그러나 이것은 유형이기 때문에 UnmodifiableMapUnmodifiableMap 유형의 개인 변수 'm'을 통해 액세스해야합니다. 아래 코드에서 getModifiableEnvironmentMap2를 참조하십시오.
필자의 경우 테스트를 위해 일부 환경 변수를 제거해야했습니다 (다른 변수는 변경되지 않아야 함). 그런 다음 테스트 후 환경 변수를 이전 상태로 복원하고 싶었습니다. 아래의 루틴은 바로 수행 할 수 있도록합니다. OS X에서 두 버전의 getModifiableEnvironmentMap을 테스트했으며 두 버전 모두 동일하게 작동합니다. 이 스레드의 주석을 기반으로하지만 환경에 따라 다른 것보다 더 나은 선택 일 수 있습니다.
참고 : 'theCaseInsensitiveEnvironmentField'에 대한 액세스는 Windows와 관련이 없으므로 테스트 할 방법이 없었지만 추가하는 것이 간단하므로 추가하지 않았습니다.
private Map<String, String> getModifiableEnvironmentMap() {
try {
Map<String,String> unmodifiableEnv = System.getenv();
Class<?> cl = unmodifiableEnv.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Map<String,String> modifiableEnv = (Map<String,String>) field.get(unmodifiableEnv);
return modifiableEnv;
} catch(Exception e) {
throw new RuntimeException("Unable to access writable environment variable map.");
}
}
private Map<String, String> getModifiableEnvironmentMap2() {
try {
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theUnmodifiableEnvironmentField = processEnvironmentClass.getDeclaredField("theUnmodifiableEnvironment");
theUnmodifiableEnvironmentField.setAccessible(true);
Map<String,String> theUnmodifiableEnvironment = (Map<String,String>)theUnmodifiableEnvironmentField.get(null);
Class<?> theUnmodifiableEnvironmentClass = theUnmodifiableEnvironment.getClass();
Field theModifiableEnvField = theUnmodifiableEnvironmentClass.getDeclaredField("m");
theModifiableEnvField.setAccessible(true);
Map<String,String> modifiableEnv = (Map<String,String>) theModifiableEnvField.get(theUnmodifiableEnvironment);
return modifiableEnv;
} catch(Exception e) {
throw new RuntimeException("Unable to access writable environment variable map.");
}
}
private Map<String, String> clearEnvironmentVars(String[] keys) {
Map<String,String> modifiableEnv = getModifiableEnvironmentMap();
HashMap<String, String> savedVals = new HashMap<String, String>();
for(String k : keys) {
String val = modifiableEnv.remove(k);
if (val != null) { savedVals.put(k, val); }
}
return savedVals;
}
private void setEnvironmentVars(Map<String, String> varMap) {
getModifiableEnvironmentMap().putAll(varMap);
}
@Test
public void myTest() {
String[] keys = { "key1", "key2", "key3" };
Map<String, String> savedVars = clearEnvironmentVars(keys);
// do test
setEnvironmentVars(savedVars);
}