Skip to content

Commit 3cdac62

Browse files
authored
Merge pull request #68 from webcompere/interoperability-with-other-libraries
Provide backwards compatibility for tools that should be able to mock the environment
2 parents 2a472d1 + fbcb134 commit 3cdac62

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

system-stubs-core/src/main/java/uk/org/webcompere/systemstubs/environment/EnvironmentVariableMocker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class EnvironmentVariableMocker {
3030
private static final Map<String, String> ORIGINAL_ENV;
3131

3232
static {
33-
ORIGINAL_ENV = System.getenv();
33+
ORIGINAL_ENV = new HashMap<>(System.getenv());
3434
try {
3535
Instrumentation instrumentation = ByteBuddyAgent.install();
3636
installInterceptorIntoBootLoader(instrumentation);

system-stubs-core/src/test/java/uk/org/webcompere/systemstubs/PropertiesFileLoadingTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ void can_load_properties_from_resources() throws Exception {
1616
new EnvironmentVariables()
1717
.set(fromResource("test.properties"))
1818
.execute(() -> {
19+
assertThat(System.getenv()).containsEntry("value1", "foo").containsEntry("value2", "bar");
1920
assertThat(System.getenv("value1")).isEqualTo("foo");
2021
assertThat(System.getenv("value2")).isEqualTo("bar");
2122
});

system-stubs-interceptor/src/main/java/uk/org/webcompere/systemstubs/internal/ProcessEnvironmentInterceptor.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import java.util.*;
66

7-
import static java.util.stream.Collectors.toMap;
7+
import static java.util.stream.Collectors.toSet;
88

99
/**
1010
* Plugs into the boot loader to provide an alternative implementation to ProcessEnvironment
@@ -13,6 +13,9 @@
1313
public class ProcessEnvironmentInterceptor {
1414
private static Map<String, String> CURRENT_ENVIRONMENT_VARIABLES = new HashMap<>();
1515

16+
@SuppressFBWarnings("URF_UNREAD_FIELD")
17+
private static Map<String, String> theEnvironment;
18+
1619
/**
1720
* For use by the EnvironmentMocker - this overwrites the effective environment variables that the system
1821
* appears to have.
@@ -21,15 +24,19 @@ public class ProcessEnvironmentInterceptor {
2124
@SuppressFBWarnings("EI_EXPOSE_STATIC_REP2")
2225
public static void setEnv(Map<String, String> env) {
2326
CURRENT_ENVIRONMENT_VARIABLES = env;
27+
28+
// this copy exposes process environment to tools looking to mock it
29+
theEnvironment = Collections.unmodifiableMap(CURRENT_ENVIRONMENT_VARIABLES);
2430
}
2531

2632
/**
2733
* The equivalent of <code>getenv</code> in the original ProcessEnvironment, assuming that
2834
* mocking is "turned on"
2935
* @return the current effective environment
3036
*/
37+
@SuppressFBWarnings("MS_EXPOSE_REP")
3138
public static Map<String, String> getenv() {
32-
return filterNulls(CURRENT_ENVIRONMENT_VARIABLES);
39+
return Collections.unmodifiableMap(filterNulls(CURRENT_ENVIRONMENT_VARIABLES));
3340
}
3441

3542
/**
@@ -47,7 +54,7 @@ public static String getenv(String name) {
4754
* @return the environment map
4855
*/
4956
public static Map<String, String> environment() {
50-
return getenv();
57+
return new HashMap<>(getenv());
5158
}
5259

5360
/**
@@ -129,10 +136,14 @@ public static byte[] toEnvironmentBlock(Map<String, String> m, int[] envc) {
129136
}
130137

131138
private static Map<String, String> filterNulls(Map<String, String> currentMockedEnvironment) {
132-
return currentMockedEnvironment.entrySet()
139+
var nullsToRemove = currentMockedEnvironment.entrySet()
133140
.stream()
134-
.filter(entry -> entry.getValue() != null)
135-
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
141+
.filter(entry -> entry.getValue() == null)
142+
.map(Map.Entry::getKey)
143+
.collect(toSet());
144+
145+
nullsToRemove.forEach(currentMockedEnvironment::remove);
146+
return currentMockedEnvironment;
136147
}
137148

138149
@SuppressFBWarnings("SE_COMPARATOR_SHOULD_BE_SERIALIZABLE")

system-stubs-jupiter/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
<scope>test</scope>
4646
</dependency>
4747

48+
<dependency>
49+
<groupId>org.junit-pioneer</groupId>
50+
<artifactId>junit-pioneer</artifactId>
51+
<version>2.1.0</version>
52+
<scope>test</scope>
53+
</dependency>
54+
4855
<dependency>
4956
<groupId>org.springframework.boot</groupId>
5057
<artifactId>spring-boot-starter-web</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package uk.org.webcompere.systemstubs.jupiter.compatibility;
2+
3+
import org.junit.jupiter.api.Nested;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.condition.EnabledForJreRange;
6+
import org.junit.jupiter.api.condition.JRE;
7+
import org.junit.jupiter.api.extension.ExtendWith;
8+
import org.junitpioneer.jupiter.SetEnvironmentVariable;
9+
import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
10+
import uk.org.webcompere.systemstubs.jupiter.SystemStub;
11+
import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
@EnabledForJreRange(max = JRE.JAVA_16)
16+
class DoesNotPreventJUnitPioneerFromWorkingTest {
17+
18+
@Nested
19+
@ExtendWith(SystemStubsExtension.class)
20+
static class StubsWorks {
21+
@SystemStub
22+
private EnvironmentVariables variables;
23+
24+
@Test
25+
void canStubVariable() {
26+
variables.set("MACHINE", "hot");
27+
28+
assertThat(System.getenv("MACHINE")).isEqualTo("hot");
29+
}
30+
}
31+
32+
@Nested
33+
@SetEnvironmentVariable(key="MACHINE", value="COLD")
34+
static class PioneerWorks {
35+
@Test
36+
void canPioneerVariable() {
37+
assertThat(System.getenv("MACHINE")).isEqualTo("cold");
38+
}
39+
}
40+
41+
}

0 commit comments

Comments
 (0)