Engineering Full Stack Apps with Java and JavaScript
Test Spring code that uses Profiles using JUnit.
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.
Should have setup and configured the environment.
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.
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 {}
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());
}
}
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.