sp00m
sp00m

Reputation: 48817

Specifying a Maven profile when running JUnit tests within a Spring webapp

Background

/pom.xml

...
<properties>
    ...
    <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
    <jdbc.url>jdbc:mysql://${database.host}/${database.name}</jdbc.url>
    <jdbc.user>${database.user}</jdbc.user>
    <jdbc.password>${database.password}</jdbc.password>
    ...
</properties>
...
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            ...
            <database.name>database</database.name>
            <database.host>localhost</database.host>
            <database.user>root</database.user>
            <database.password></database.password>
            ...
        </properties>
    </profile>
</profiles>
...

/src/main/resources/database.properties

...
jdbc.driver=${jdbc.driver}
jdbc.url=${jdbc.url}
jdbc.user=${jdbc.user}
jdbc.password=${jdbc.password}
...

/src/main/resources/spring/applicationContext.xml

<beans ... xmlns:p="http://www.springframework.org/schema/p" ...>
    ...
    <bean
        id="dataSource"
        ...
        p:driverClassName="${jdbc.driver}"
        p:url="${jdbc.url}"
        p:username="${jdbc.user}"
        p:password="${jdbc.password}"
        ... />
    ...
</beans>

/src/test/java/com/company/project/service/MyItemServiceImplTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/spring/applicationContext.xml" })
public class MyItemServiceImplTest {

    @Resource
    private MyItemService myItemService;

    @Test
    public void testSave() {
        MyItem myItem = new MyItem();
        myItemService.save(myItem);
        ...
    }

}

Question

When running the tests, it throws an exception:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in class path resource [spring/applicationContext.xml]: Could not resolve placeholder 'database.password'
...

I guess it's because I need to run the tests while specifying the dev profile like I do when I launch the webapp (using -P dev). But I can't make it work. Is it even possible?

PS

The filtered applicationContext.xml file (i.e. the one in /target/classes/spring/applicationContext.xml) is identical to the one in /src/*, but the filtered database.properties file (i.e. /target/classes/database.properties) looks like

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://${database.host}/${database.name}
jdbc.user=${database.user}
jdbc.password=${database.password}

It means that from the pom.xml file to the .properties one, the properties have been well filtered, but within the pom.xml itself, the properties that depend on the chosen profile won't get filtered. Probably because I want to specify anywhere the profile I need when launching the tests. But as I said before, -P dev doesn't seem work with JUnit...

Upvotes: 2

Views: 11425

Answers (1)

maba
maba

Reputation: 48055

Resource filtering is performed in the process-resources phase. So if you state mvn test -Pdev you will have passed that phase and all filtering has been done. It doesn't matter to JUnit what profile you are running since you are not doing anything else differently in that dev profile.

Upvotes: 3

Related Questions