JUNIT Testing of Spring Code with Profiles Example

We can enable profiles from within a JUNIT test using @ActiveProfiles annotation. If you don't specify one, profile will be activated based on property value. This excercise writing JUNIT is applicable for code without profiles also: you just have to not activate any profiles.

We will test the same bean component classes that we created @ http://javajee.com/enabling-spring-profiles-in-a-standalone-java-applica.... Though we can reuse the same java configuration class, we will create a separate config class for test, as it is a common practice in enterprises. We will also create a test.properties file in classpath intead of application.properties to specify the active profile.

 

Working with Maven

If you are working with Maven, you need to add below dependencies to your POM file:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.2.6.RELEASE</version>
</dependency>  

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

 

You will also have to take care of below things if you are working with Maven:

  • You should place your test classes inside the src/test/java folder in a package similar to your original classes.

  • Any files that needs to be read from classpath has to be placed in src/test/resources folder.

 

Example Code: Config and properties

We will create a new properties file test.properties with active profile details:

spring.profiles.active=dbprofile

This will be used if we are not specifying a profile using @ActiveProfiles annotation.

 

Example Code: TestConfig.java

package com.javajee.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:/test.properties")
@ComponentScan(basePackages="com.javajee.spring")
public class TestConfig {

}

 

Example Code: JUNIT Test Classes

JJDatabaseWriterTest.java

package com.javajee.spring;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.javajee.spring.JJWriter;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
@ActiveProfiles("dbprofile")
public class JJDatabaseWriterTest {

    @Autowired
    JJWriter jjwriter;
    
    @Test
    public void testJJDatabaseWriterToString()
    {
        Assert.assertEquals("Writing to Database!!!", jjwriter.toString());
    }
    
}

 

JJFileWriterTest.java

package com.javajee.spring;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.javajee.spring.JJWriter;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
@ActiveProfiles("fileprofile")
public class JJFileWriterTest {

    @Autowired
    JJWriter jjwriter;
    
    @Test
    public void testJJDatabaseWriterToString()
    {
        Assert.assertEquals("Writing to File!!!", jjwriter.toString());
    }
    
}

 

JJWriterTest.java

This class is just to test the default scenario when no active profiles are specified, and might not be required in an actual use case.

package com.javajee.spring;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.javajee.spring.JJWriter;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
public class JJWriterTest {

    @Autowired
    JJWriter jjwriter;
    
    @Test
    public void testJJDatabaseWriterToString()
    {
        Assert.assertEquals("Writing to Database!!!", jjwriter.toString());
    }
    
}

 

Executing Tests

You can now right click and run each of these tests as JUnit tests to see the results. Modify things and play around to see positive and negative cases.

 

Refactoring Test Classes

As you can see, below annotations are repeated across all test classes:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })

 

You can move any such repeated annotations to an appropriate parent class and then extend from it, but is not a requirement. 

MyAbstractSpringTest.java

package com.javajee.spring;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
public class MyAbstractSpringTest {

}

 

Now I can change my test cases as: 

package com.javajee.spring;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;

import com.javajee.spring.JJWriter;

@ActiveProfiles("dbprofile")
public class JJDatabaseWriterTest extends AbstractSpringTest{

    @Autowired
    JJWriter jjwriter;
    
    @Test
    public void testJJDatabaseWriterToString()
    {
        Assert.assertEquals("Writing to Database!!!", jjwriter.toString());
    }
    
}

Note that only additional annotations need to be specified. You can also change your config class for tests all at once.

I am not going into any debate on whether to do this or not, but wanted to show that this is possible.

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!