Spring boot #Import for loading config integration test not working - spring

I have a simple spring boot app and i am implementing some integration test. I have 2 classes one that will hold my common configuration (Demo3ApplicationTests ) and the other one my integration test class(DumyClassTest), please find below it is empty for the time being:
#SpringBootTest(classes = Demo3Application.class)
class Demo3ApplicationTests {
#Test
void contextLoads() {
}
}
My integration test class:
#Import(value = Demo3ApplicationTests.class)
public class DumyClassTest{
#Autowired
DemoService demoService;
#Test
public void testImportConfig() {
demoService.logDummyMsg();
}
}
When I run the test testImportConfig the demoService value is null as I guess the #import i am not setting it up correctly. However when I extends that is DumyClassTest extends Demo3ApplicationTests the demoService is not null and the test is run correctly.
Any idea why when I use the import annotation the demoService is null?
Thanks in advance.

Related

#EnableCaching gets ignored when multiple Junit Tests are run together

I have a set of Junit test cases for a Spring Boot application which are annotated with #EnableCaching annotation. When these Junit tests are run individually it works fine. But when run together with the other Junit test classes , the #EnableCaching annotation seems to get ignored.
I'm using the #DirtiesContext annotation to clean the context after each test method. But this doesnt seem to be making any difference to the above mentioned issue.
Please let me know if #EnableCaching can be used in Junit Tests or not.
Please find below a sample code of the Junit Test class.
#EnableCaching
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#TestPropertySource(properties = { "a,b,c" })
#DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class SampleTest {
#BeforeEach
void setUpTest() {
//setup steps
}
#Test
void testCacheable(){
String result = controller.testCache();
}
}
#RestController
public class TestController {
#RequestMapping("/testCache")
#Cacheable(cacheNames="cache")
public String testCache() throws InterruptedException {
logger.info("Returning NOT from cache");
return "cache";
}
}

Spring Junit Exception -- java.lang.IllegalStateException: Found multiple #SpringBootConfiguration annotated classes

I have a SpringBoot Project and it has two classes annotated with #SpringBootApplication.
I have written a junit test like this
#RunWith(SpringRunner.class)
#WebMvcTest(value = TestController.class)
public class Test1 {
#Test
public void test1(){
}
}
When i run this test am getting exception
java.lang.IllegalStateException: Found multiple #SpringBootConfiguration annotated classes.
I want the test to load only the controller and not the complete context.
Any help on this?
Try to add #ContextConfiguration annotation to your test class.
#RunWith(SpringRunner.class)
#ContextConfiguration(classes=Application.class)
#WebMvcTest(value = TestController.class)
public class Test1 {
#Test
public void test1(){
}
}

How to inject a service component in Spring Test class using Kotlin?

I am trying to test the business logic/services. Using Kotlin in my Spring Boot application, I am trying to instantiate my services, using the test class constructor. But this is not allowed, as I am getting a ParameterResolutionException.
This is my code:
#SpringBootTest
class IntermediateApplicationTests(val ticketService: TicketService) {
#Test
fun contextLoads() {
}
}
How can I achieve this?
Thanks for every help!
You can use the #Autowired annotation to do this:
#SpringBootTest
class IntermediateApplicationTests #Autowired constructor(
val ticketService: TicketService
) {
#Test
fun contextLoads() {
}
}
In fact this is the recommended way of doing injection and the IDEA Spring plugin will complain if you do it some other way.

Spring Junit and annotation based autowiring

I added a junit test to a simple spring example but it fails to autowire the json service that I wrote.
What is needed to get autowiring to work in a spring JUnit tests?
To try the failing project out do ...
git clone https://bitbucket.org/oakstair/spring-boot-cucumber-example
cd spring-boot-cucumber-example
./gradlew test
Thanks in advance!
Application
#SpringBootApplication
#ComponentScan("demo")
public class DemoApplication extends SpringBootServletInitializer {
Service interface
#Service
public interface JsonUtils {
<T> T fromJson(String json, Class<T> clazz);
String toJson(Object object);
}
Service implementation
#Component
public class JsonUtilsJacksonImpl implements JsonUtils {
Test
#ContextConfiguration()
#RunWith(SpringJUnit4ClassRunner.class)
#ComponentScan("demo")
public class JsonUtilsTest {
#Autowired
private JsonUtils jsn;
In your JsonUtilsTest you can't put a #ComponentScan on the class level here since it isn't a #Configuration class. With a #ContextConfiguration annotation like you are using here it is first looking for a static inner #Configuration class so add one of those with the #ComponentScan and it should work:
#ContextConfiguration()
#RunWith(SpringJUnit4ClassRunner.class)
public class JsonUtilsTest {
#Autowired
private JsonUtils jsn;
#Test
// Note: This test is not tested since I haven't got autowiring to work.
public void fromJson() throws Exception {
Integer i = jsn.fromJson("12", Integer.class);
assertEquals(12, (int) i);
}
#Test
// Note: This test is not tested since I haven't got autowiring to work.
public void toJson() throws Exception {
assertEquals("12", jsn.toJson(new Integer(12)));
}
#Configuration
#ComponentScan("demo")
public static class TestConfiguration {
}
}
EDIT: Or you can make Spring boot do the work for you by using the #SpringBootTest annotation with a SpringRunner instead:
#RunWith(SpringRunner.class)
#SpringBootTest
public class JsonUtilsTest {
Adding this to the test class fixed my problems!
#ContextConfiguration(classes = {DemoApplication.class})
Add #SpringBootTest
On your test class
And provide your SpringBootApplication class and Json utils class to the classes field of #SpringBootTest
It should look like this
#ContextConfiguration()
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes={<package>.DemoApplication.class, <package>.JsonUtil.class } )
#ComponentScan("demo")
public class JsonUtilsTest {

SpringJUnit4ClassRunner with JUnit testsuite error

I am trying to setup Junit test suite with Spring for the first time and tried with couple of changes in my classes, but no luck and ended up with this error : "junit.framework.AssertionFailedError: No tests found in Myclass"
Briefly, I have 2 test classes both are from same base class which loads Spring context as below
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration( locations =
{
"classpath:ApplicationContext.xml"
})
I tried adding those 2 test classes into a suite as below
#RunWith( SpringJUnit4ClassRunner.class )
#SuiteClasses({ OneTest.class, TwoTest.class })
public class MyTestSuite extends TestCase {
//nothing here
}
I am running this test suite from ant. But, this gives me an error saying "No tests found"
However, If I run the individual 2 test cases from ant, they work properly. Not sure why is this behaviour, I am sure missing something here. Please advice.
As mentioned in the comments, we run the TestSuite with #RunWith(Suite.class) and list all the test cases with #SuiteClasses({}). In order to not repeat the #RunWith(SpringJunit4ClassRunner.class) and #ContextConfiguration(locations = {classpath:META-INF/spring.xml}) in each test case, we create an AbstractTestCase with these annotations defined on it and extend this abstract class for all test cases. A sample can be found below:
/**
* An abstract test case with spring runner configuration, used by all test cases.
*/
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations =
{ "classpath:META-INF/spring.xml" })
public abstract class AbstractSampleTestCase
{
}
public class SampleTestOne extends AbstractSampleTestCase
{
#Resource
private SampleInterface sampleInterface;
#Test
public void test()
{
assertNotNull(sampleInterface);
}
}
public class SampleTestTwo extends AbstractSampleTestCase
{
#Resource
private SampleInterface sampleInterface;
#Test
public void test()
{
assertNotNull(sampleInterface);
}
}
#RunWith(Suite.class)
#SuiteClasses(
{ SampleTestOne.class, SampleTestTwo.class })
public class SampleTestSuite
{
}
If you don't want to have an AbstractSampleTest, then you need to repeat the spring runner annotations on each test case, until Spring comes up with a SpringJunitSuiteRunner similar to how they need to add a SpringJunitParameterizedRunner.

Resources