[Recipe] JUNIT Testing of Spring Code with Profiles

Problem: 

Test Spring code that uses Profiles using JUnit. 

Solution Summary: 

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.

Prerequisites: 

Should have setup and configured the environment. 

Solution: 

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.

 

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 {

}

 

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.

Recipe Tags: 

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)