Irina Avram
Irina Avram

Reputation: 1522

Make Spring JUnit Test run on test database

I would like to configure my JUnit Tests to run on a different database than the one the Application runs on. I've been doing this for hours but have had no success so far. Tried configuring it using the application.properties file and the spring config file but nothing worked. So how can this be accomplished? Any help would be greatly appreciated.

Here is my test file:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.profiles.active=test")
public class TestContactController extends AbstractTest {

    @Autowired
    private MockMvc mvc;

    @Test
    @Rollback
    public void testAddContact() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/contact/add").contentType(MediaType.APPLICATION_JSON)
            .content("{\n" +
                    "\t\"authCode\": \"daca824a0bf04d038543373adfdb2c8f\",\n" +
                    "\t\"requestData\":{\n" +
                    "\t\t\"firstName\": \"Max\",\n" +
                    "\t\t\"lastName\": \"Mustermann\",\n" +
                    "\t\t\"category\": {\n" +
                    "\t\t\t\"id\": " + categoryId + "\n" +
                    "\t\t}, \"partOfOrgUnit\": {\n" +
                    "\t\t\t\"id\": " + companyId + "\n" +
                    "\t\t}\n" +
                    "\t}\n" +
                    "}"))
            .andExpect(status().isOk())
            .andExpect(content().string(equalTo("{\"success\":true,\"message\":\"SUCCESS: Contact added successfully\"}")));
    }
}

My persistence xml, with the two databases:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
         version="2.0">
    <persistence-unit name="sab_pu">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3307/projectdb?serverTimezone=UTC"/>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value="root"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="javax.persistence.validation.mode" value="NONE"/>
        </properties>
    </persistence-unit>
    <persistence-unit name="sab_test_pu">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3307/testdb?serverTimezone=UTC"/>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value="root"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="javax.persistence.validation.mode" value="NONE"/>
        </properties>
    </persistence-unit>
</persistence>

And this is my .properties file:

spring.datasource.url=jdbc:mysql://localhost:3307/testdb?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

Exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.SAB.test.testsController.TestContactController':
Unsatisfied dependency expressed through field 'mvc'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

Upvotes: 4

Views: 12097

Answers (1)

hesch
hesch

Reputation: 134

Do you have the possibility to use Spring Boot? It offers you a 'plain' Servlet-based deployment into a already existing Tomcat instance, too. My last plain Spring sessions are too fare away.

I can give you an example for Nikos answer with Spring Boot and assume that you'r using Maven.

In Spring Boot its possible to configure most things with a application.properties file. This includes the setup for a persistence.xml file, too.

For your productive environment create a application.properties file in src > main > resources with content like this.

spring.datasource.url=jdbc:mysql://localhost:3307/projectdb?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto: create-drop
spring.jpa.show-sql=true

The test environment needs a file named application-test.properties with this content.

spring.datasource.url=jdbc:mysql://localhost:3307/testdb?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

As you can see, for testing you don't need to repeat everything, just the stuff which changed.

Now you can test your application to run in productive mode by just starting the application. In your console you should see that Spring Boot uses MySQL. If you want use your testing setup add -Dspring.profiles.active=test as JVM parameter.

After this steps, let's switch to your JUnit test which looks like this.

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.profiles.active=test")
@AutoConfigureMockMvc
public class MeTest {
    @Test
    public void testMe() {
        System.out.println("Hello World!");
    }
}

The @SpringBootTest sets the current profile to test and starts the JUnit test run.

This is just one possible way for your problem. I hope it helps you and everything works because I have no MySQL database on my working machine.

Upvotes: 5

Related Questions