Jonathan Lebrun Jonathan Lebrun - 4 months ago 42
Java Question

Eclipse Maven: run test with spring profile

I want to run maven with different profile but it seems not working.
I created 2 differents java class for my JPAConfiguration :

JPAConfiguration.class and JPAConfigurationTest.class

@Configuration
@Profile({"dev"})
@EnableTransactionManagement(proxyTargetClass = true)
@EnableJpaRepositories(basePackages = { "com.jle.athleges.model.repository", "com.jle.athleges.security.repository" })
@ComponentScan(basePackages = { "com.jle.athleges.model.services", "com.jle.athleges.security.services" })
public class JpaConfiguration {

@Bean
public DataSource dataSource() throws SQLException {
System.out.println("use dev");
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
builder.setName("dev");
return builder.setType(EmbeddedDatabaseType.H2).build();
}

@Bean
public EntityManagerFactory entityManagerFactory() throws SQLException {

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);

LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.jle.athleges.model.entity", "com.jle.athleges.security.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();

}

@Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}

@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}

@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}

}

@Configuration
@Profile({"test"})
@EnableTransactionManagement(proxyTargetClass = true)
@EnableJpaRepositories(basePackages = { "com.jle.athleges.model.repository", "com.jle.athleges.security.repository" })
@ComponentScan(basePackages = { "com.jle.athleges.model.services", "com.jle.athleges.security.services" })
public class JpaConfigurationTest {

@Bean
public DataSource dataSource() throws SQLException {
System.out.println("use test");
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
builder.setName("test");
return builder.setType(EmbeddedDatabaseType.H2).build();
}

@Bean
public EntityManagerFactory entityManagerFactory() throws SQLException {

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);

LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.jle.athleges.model.entity", "com.jle.athleges.security.entity");
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();

}

@Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}

@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}

@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}

}


In my pom.xml, I have this :

<project>



<dependencies>



</dependencies>

<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
</profile>
</profiles>


<build>
<finalName>AthleGes</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<debug>true</debug>
</configuration>
</plugin>

</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<jettyEnvXml>src/test/resources/jetty-env.xml</jettyEnvXml>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>


And finally, I have a test class :

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles(profiles = {"test","dev"})
@ContextConfiguration(classes = { JpaConfigurationTest.class, JpaConfiguration.class, SecurityConfig.class })
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
})
public class MemberServiceImpTest {

static Logger log = LoggerFactory.getLogger(MemberServiceImpTest.class);

@Autowired
private MemberService memberService;

@Autowired
private MemberRepository repository;

@Before
public void setUp(){
repository.deleteAll();
}

@Test
public void saveMember() {

log.debug("Start saveMember");
Member a = new Member();
a.setFirstname("aaa");
a.setLastname("hhh");
a.setId(0L);

Assert.assertNotNull(memberService.save(a));

log.debug("End saveMember");
}

@Test
public void getAllMembers() {
log.debug("Start getAllMember");

long sizeBefore = repository.count();
Member a = new Member();
a.setFirstname("aaa");
a.setLastname("hhh");
a.setId(2L);

Member b = new Member();
b.setFirstname("aaa");
b.setLastname("hhh");
b.setId(1L);
memberService.save(a);
memberService.save(b);

Assert.assertEquals(memberService.getAll().size(),sizeBefore + 2);
log.debug("End getAllMember");
}
}


When I run my unit test from Eclipse, it is working fine. If I move the profile in the test class from dev to test and from test to dev, it is working. I mean the test pass and the displayed message "use dev" or "use test" is displayed.

I want to run the tests from maven (with m2e) and I created this configuration :

Eclipse-Maven-Configuration

But when I change the profile, test is always started.

I tried to activate profile from Maven -> Select Maven Profile but I have been the same result.

I miss something but I don't know what. I don't understand.

Could you help me?

Thanks

Answer

As per your configuration @ActiveProfiles, both the profiles will be activated during your test execution. If you want to control the active spring profile for test cases through maven, then I would suggest you to remove @ActiveProfiles annotation from your test class and specify spring.profiles.active as a system property. You could do it using either of the following ways:

Set it in the maven surefire plugin configurtion:

<project>
    <properties>
       <spring.profiles.active>dev</spring.profiles.active>
    </properties>

    <profiles>
      <profile>
        <id>dev</id>
        <activation>
            <property>
                <name>spring.profiles.active</name>
                <value>dev</value>
            </property>
        </activation>
      </profile>
      <profile>
        <id>test</id>
        <activation>
            <property>
                <name>spring.profiles.active</name>
                <value>test</value>
            </property>
        </activation>
      </profile>
    </profiles>

       <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <argLine>-Dspring.profiles.active=${spring.profiles.active}</argLine>
                    </configuration>
                </plugin>
            </plugins>
        </build>

</project>

You can simply run maven test as you are doing already by passing spring.profiles.active parameter without the profile name. Profile will be activated automatically using value of the property spring.profiles.active

OR

Pass it to surefire plugin through maven parameter during execution like:

mvn -DargLine="-Dspring.profiles.active=dev"