Зачем использовать свойства системы, а не свойства приложения. Если у вас хорошо сконфигурированный проект Maven, эту проблему можно решить, просто выделив ваши свойства в конфигурации пакета и добавив несколько фильтров Maven для разработки, qa, этапа или профилей производства.
Структура проекта должна быть такой:
my-project
|_ src
| |_ main
| | |_ filters
| | | |_ development.properties
| | | |_ local.properties
| | | |_ production.properties
| | | |_ qa.properties
| | |_ java
| | | |_artifact
| | | |_ MySingleton.java
| | |_ resources
| | |_ my-configurations.properties
| |_ test
| | |_ java
| | | |_artifact
| | | |_ MySingletonTest.java
|_ pom.xml
Maven конфигурации файл проекта (pom.xml) должны объявить фильтры профиля:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gvillacis</groupId>
<artifactId>test-units</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<profiles>
<profile>
<id>local</id>
<properties>
<deployEnvironment>local</deployEnvironment>
</properties>
</profile>
<profile>
<id>development</id>
<properties>
<deployEnvironment>development</deployEnvironment>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<deployEnvironment>qa</deployEnvironment>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<deployEnvironment>production</deployEnvironment>
</properties>
</profile>
</profiles>
<build>
<filters>
<filter>src/main/filters/${deployEnvironment}.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<targetPath>${project.build.outputDirectory}</targetPath>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
MySingleton.class содержит это:
package artifact;
import java.util.ResourceBundle;
public class MySingleton {
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("my-configurations");
private static MySingleton instance;
private String value1 = BUNDLE.getString("value.1");
private String value2 = BUNDLE.getString("value.2");
public void doSomething() {
System.out.println("The value of 1st property is: " + value1);
System.out.println("The value of 2nd property is: " + value2);
}
public static MySingleton getInstance() {
if (instance == null) {
instance = new MySingleton();
}
return instance;
}
}
MySingletonTest.class содержит следующее:
package artifact;
import org.junit.Test;
public class MySingletonTest {
@Test
public void testDoSomething() {
MySingleton singleton = MySingleton.getInstance();
singleton.doSomething();
}
}
my-configurations.properties constains это:
value.1=${filter.value.1}
value.2=${filter.value.2}
value.3=${filter.value.3}
value.4=${filter.value.4}
value.5=${filter.value.5}
А для «местных.Свойства»Пример профиля вы могли бы это:
filter.value.1=1
filter.value.2=2
filter.value.3=3
filter.value.4=4
filter.value.5=5
Теперь, в зависимости от профиля, связанных с окружающей средой, которые вы хотите проверить, вы можете использовать такую команду:
$ mvn test -P local
Это то, что я получить, когда я выполнить команду для локального профиля:.
$ mvn test -P local
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building test-units 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ test-units ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource to /home/gvillacis/Work/workspaces/testunits/target/classes
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ test-units ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ test-units ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/gvillacis/Work/workspaces/testunits/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ test-units ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ test-units ---
[INFO] Surefire report directory: /home/gvillacis/Work/workspaces/testunits/target/surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running MySingletonTest
The value of 1st property is: 1
The value of 2nd property is: 2
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.067 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.042 s
[INFO] Finished at: 2017-01-24T18:58:24-03:00
[INFO] Final Memory: 12M/253M
[INFO] ------------------------------------------------------------------------
Существует только один ответ: вы не можете! Нет (подходящего) способа создания более одного экземпляра для одноэлементного. В принципе, вы нашли реальную проблему в своей программе: синглтоны - плохие кандидаты на модульное тестирование. – Seelenvirtuose
«без необходимости изменять класс Java», зачем связывать руки за спиной? –
Вместо того, чтобы спрашивать, как его проверить без изменения класса singleton, вы должны воспользоваться этой возможностью и изменить ее. Первый шаг: ваш класс выполняет две функции: 1) его функциональность заключается в том, чтобы делать некоторые записи. 2) Он считывает конфигурацию (из некоторого жестко закодированного места). Решением этого является разделение конфигурации на собственный класс (или интерфейс). – Seelenvirtuose