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

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(){
}
}

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 boot #Import for loading config integration test not working

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.

Mocking an Aspect class invoked after an exception is thrown in Junit

I have an aspect class as below -
public class TestAspect {
#AfterThrowing(pointcut = "execution(* *(..)) ", throwing = "testException")
public void afterThrowAdvice(TestException testException) throws Exception {
}
}
Now anytime any class throws TestException, TestAspect's afterThrowAdvice method is getting called. From Unit tests as well without using any spring configuration xmls, running as a plain junit test. How do I mock to not do anything when that method is called? I tried in my unit test the below but it won't work. Rightly so because the aspect is not autowired into the classes I am testing. Any suggestions? -
#Mock
private TestAspect testAspect
doNothing.when(testAspect).afterThrowAdvice(any(TestException.class));
One way to achieve this is using #Profile option .
Following profile configuration will make sure the aspect bean is only available with the profile is not test
#Component
#Aspect
#Profile("!test")
public class TestAspect {
#AfterThrowing(pointcut = "execution(* *(..)) ", throwing = "testException")
public void afterThrowAdvice(TestException testException) throws Exception {
...
}
}
and following Junit testcase runs the the tests with profile as test and no aspect bean is created here
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestExConfig.class)
#ActiveProfiles("test")
public class TestService{
#Autowired
ServiceWithException service;
#Test(expected = TestException.class)
public void testExceptionMethod() throws TestException {
service.testMethod();
}
}
Hope this helps

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 {

Get access to spring context from JUnit test

I try to run test for spring framework. I use only the xml context. In test (JUnit) class I specify
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"springContext.xml"})
public class MyTest extends TestCase {
#Test
public void test() {
}
}
but I don't know how to get access to the spring context in the #Test method? I don't can use of #Autowired annotation, because I don't use annotation driven context
The test class is like a regular bean. So far you can use both of those in your test class:
autowire ApplicationContext
implement ContextAware interface
See How to inject ApplicationContext itself

Resources