Bu iş parçacığını bulan çoğu insan gibi, bazı birim testleri yazıyordum ve testin çalışması için doğru koşulları ayarlamak üzere ortam değişkenlerini değiştirmem gerekiyordu. Ancak, en çok oylanan cevapların bazı sorunları olduğunu ve / veya çok şifreli veya aşırı karmaşık olduğunu buldum. Umarım bu başkalarının çözümü daha hızlı çözmesine yardımcı olur.
Öncelikle, @Hubert Grzeskowiak'ın çözümünün en basit çözüm olduğunu gördüm ve benim için çalıştı. Keşke ilk önce buna gelseydim. @Edward Campbell'ın cevabına dayanıyor, ancak döngü araması için karmaşık değil.
Ancak, en çok oy alan @ pushy'nin çözümüyle başladım. @Anonymous ve @Edward Campbell'ın bir birleşimidir. @pushy, hem Linux hem de Windows ortamlarını kapsamak için her iki yaklaşımın da gerekli olduğunu iddia ediyor. Ben OS X altında çalışan ve her ikisi de işe (bir kez @anonymous yaklaşım ile ilgili bir sorun düzeltildi) bulmak. Diğerlerinin de belirttiği gibi, bu çözüm çoğu zaman işe yarar, ancak hepsi işe yaramaz.
Ben karışıklığın çoğunun kaynağı @ anonymous'ın 'Çevre' alanında çalışan çözümünden geldiğini düşünüyorum. ProcessEnvironment yapısının tanımına bakıldığında , 'theEnvironment' bir Map <String, String> değil, bir Map <Değişken, Değer> 'dir. Haritayı temizlemek iyi çalışır, ancak putAll işlemi haritayı bir Harita <Dize, Dize> olarak yeniden oluşturur; bu, sonraki işlemler Harita <Değişken, Değer> 'i bekleyen normal API'yi kullanarak veri yapısı üzerinde çalıştığında sorunlara neden olabilir. Ayrıca, münferit elemanlara erişmek / kaldırmak bir problemdir. Çözüm 'TheEnvironment'a dolaylı olarak' The UnnodifiableEnvironment 'aracılığıyla erişmektir. Ancak bu bir tür Değiştirilemediğindenerişim, UnmodifiableMap türündeki 'm' özel değişkeni üzerinden yapılmalıdır. Aşağıdaki kodda getModifiableEnvironmentMap2 koduna bakın.
Benim durumumda, test için bazı ortam değişkenlerini kaldırmam gerekiyordu (diğerleri değişmemeli). Daha sonra testten sonra ortam değişkenlerini önceki durumlarına döndürmek istedim. Aşağıdaki rutinler bunu doğrudan yapar. Her iki sürümü de getModifiableEnvironmentMap'i OS X üzerinde test ettim ve her ikisi de eşdeğer çalışıyor. Bu konudaki yorumlara dayanmasına rağmen, ortama bağlı olarak biri diğerinden daha iyi bir seçim olabilir.
Not: Windows'a özgü gibi göründüğü için 'theCaseInsensitiveEnvironmentField' erişimine dahil etmedim ve test etmenin bir yolu yoktu, ancak eklemenin doğrudan doğru olması gerekir.
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);
}