简体   繁体   中英

Specifying Java path for properties file

I have a Java Spring project, configured with Maven. As the amount of unit tests and their configuration files is adding up rapidly, I'm trying to centralize the test configurations to one properties file (the same one, which is used in building the project).

The unit tests are located (relative to the project path, of course) in tree

src/test/java/com (...)

The resource files for those tests are in

src/test/resources(...)

And lastly, the properties file, which the resource file should read, is in directory

src/main/filters

Now, I have a Junit class where I specify the configuration file location like this:


@ContextConfiguration(locations = { "classpath:com/initrode/quartz/SyncManagerJobTest-context.xml"})

In the configuration file SyncManagerJobTest-context.xml there is a line


<context:property-placeholder location="/src/main/filters/deploy.local.properties"/>

This results in the properties file to be read from directory . What I'd like to read is the properties file, which is located under src/main/filters. I tried using ../../ to traverse the directory upwards, but that didn't help. Using classpath: didn't work out either. I could use an absolute path with "file:", but that would require every developer in the project to modify the configuration, which is not good either.

To summarize, the question is: how can I force the configuration file in src/test/resources/ to read the properties file in src/main/filters?

And a related bonus question: when handling files in Java environment, are there other modifiers than "file:" and "classpath:"?

If you specify src/main/filters as a resources location, Maven will move the resources to target/classes , and also compile the classes to the same location during the build. You then do not have a relative path to deal with as they have the same root. If you don't do something like this, your filters directory will not be included in the build.

Update: Of course your test code is output to target/test-classes, so to simplify the testing, you could specify that src/main/filters is copied to target/test-classes during the process-test-resources phase. I've modified the example to show that behaviour.

If you have not already done so, you can use the build-helper-maven-plugin to add the filters folder as a resource location.

The configuration to do so looks like this:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.3</version>
  <executions>
    <execution>
      <id>add-resource</id>
      <phase>process-test-sources</phase>
      <goals>
        <goal>add-test-resource</goal>
      </goals>
      <configuration>
        <resources>
          <resource>
            <directory>scr/main/filters</directory>
          </resource>
        </resources>
      </configuration>
    </execution> 
  </executions>
</plugin>

To me, it sounds a bit strange to put a properties file in src/main/filters if you don't plan to use this file as... a filter. If this file is used as a standard test resource, why don't you place it in src/test/resources ? If you want to filter some resources files, why don't you just do it and use the filtered resources? I would expect to see something like:

<build>
  <!-- Filter resources -->
  <filters>
    <filter>src/main/filters/my-filter.properties</filter>
  </filters>
  <!-- Resources for src/main -->
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource> 
  </resources>
  <!-- Resources for src/test -->
  <testResources>
    <testResource>
      <directory>src/test/resources</directory>
      <filtering>true</filtering>
    </testResource>
  </testResources>
</build> 

I may be missing something but I think you are mixing some concepts. In your case (and if I understood correctly what you are trying to do), I'd use maven profiles and filters to manage multiple environments deployment. Have a look at:

Spring allows us to specify the location of test resources separately so that they are taken up only in the testing phase.By using the @TestPropertySource("/test.properties") annotation you can specify the test property file to be loaded for tests.

@TestPropertySource is a class-level annotation that you can use to configure the locations of properties files and inlined properties to be added to the set of PropertySources in the Environment for an ApplicationContext loaded for an integration test.

You can specify this annotation in a separate configuration class which can be specified to be scanned only during testing.Example:

@Component
public class ClassUsingProperty {

@Value("${testpropertysource.one}")
private String propertyOne;

public String retrievePropertyOne() {
    return propertyOne;
 }
}

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ClassUsingProperty.class)
@TestPropertySource
public class DefaultTest {


@Autowired
ClassUsingProperty classUsingProperty;

@Test
public void givenDefaultTPS_whenVariableRetrieved_thenDefaultFileReturned() {
    String output = classUsingProperty.retrievePropertyOne();

    assertThat(output).isEqualTo("default-value");
    }
 }

Additionally, we can change the default configuration file location, or add extra properties that will have even higher precedence:

@TestPropertySource(locations = "/other-location.properties",
  properties = "baeldung.testpropertysource.one=other-property-value")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM