Issue
I am new to Mockito , I am trying to write Unit Tests for Main Class facing some issue not able to instantiate the bean. Please anyone help me to fix that issue. If anyone give me suggestion how to approach to write the unit tests in mockito for below class.
import com.ab.obs.spring.ObsSpringBootApplicationForCloud;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.ab.obs.config.EncryptDecryptUtilConfig;
import com.ab.csl.retail.core.config.HikariDataSourceConfig;
import org.springframework.context.annotation.Import;
@Import({EncryptDecryptUtilConfig.class, HikariDataSourceConfig.class})
@SpringBootApplication
@EnableAspectJAutoProxy
public class ObsDocumentApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
ObsSpringBootApplicationForCloud.initBase(application, "csl-svc-obs-test");
return application;
}
public static void main(String[] args) {
SpringApplicationBuilder application = new SpringApplicationBuilder();
ObsSpringBootApplicationForCloud.initBase(application, "csl-svc-obs-test");
application.sources(ObsDocumentApplication.class)
.run(args);
}
}
Test Class here:
import com.ab.obs.spring.ObsSpringBootApplicationForCloud;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.boot.builder.SpringApplicationBuilder;
import static org.powermock.api.mockito.PowerMockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ObsDocumentApplication.class, ObsSpringBootApplicationForCloud.class})
public class ObsDocumentApplicationTest {
@Mock
private SpringApplicationBuilder applicationBuilder;
@Before
public void setUp() throws Exception{
PowerMockito.spy(ObsDocumentApplication.class);
PowerMockito.spy(ObsSpringBootApplicationForCloud.class);
applicationBuilder = mock(SpringApplicationBuilder.class);
}
@Test
public void testMainClass() {
ObsDocumentApplication.main(new String[] {});
}
}
Error log:
java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.cloud.function.compiler.config.FunctionProxyApplicationListener
at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:467)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:449)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:442)
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:285)
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:264)
at org.springframework.boot.builder.SpringApplicationBuilder.createSpringApplication(SpringApplicationBuilder.java:109)
at org.springframework.boot.builder.SpringApplicationBuilder.<init>(SpringApplicationBuilder.java:97)
at com.sc.obs.ObsDocumentApplication.main(ObsDocumentApplication.java:25)
at com.sc.obs.ObsDocumentApplicationTest.testMainClass(ObsDocumentApplicationTest.java:31)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.compiler.config.FunctionProxyApplicationListener]: Constructor threw exception; nested exception is java.lang.ClassCastException: class com.sun.tools.javac.api.JavacTool
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:225)
at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:463)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:449)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:442)
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:285)
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:264)
at org.springframework.boot.builder.SpringApplicationBuilder.createSpringApplication(SpringApplicationBuilder.java:109)
at org.springframework.boot.builder.SpringApplicationBuilder.<init>(SpringApplicationBuilder.java:97)
at com.sc.obs.ObsDocumentApplication.main(ObsDocumentApplication.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.powermock.api.mockito.invocation.InvocationFactory$1.call(InvocationFactory.java:55)
at org.mockito.internal.invocation.RealMethod$FromCallable$1.call(RealMethod.java:40)
at org.mockito.internal.invocation.RealMethod$FromBehavior.invoke(RealMethod.java:62)
at org.mockito.internal.invocation.InterceptedInvocation.callRealMethod(InterceptedInvocation.java:141)
at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:44)
at org.mockito.Answers.answer(Answers.java:98)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:106)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:33)
at org.powermock.api.mockito.invocation.MockHandlerAdaptor.performIntercept(MockHandlerAdaptor.java:64)
at org.powermock.api.mockito.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:94)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:186)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:168)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:145)
at com.sc.obs.ObsDocumentApplication.main(ObsDocumentApplication.java)
at com.sc.obs.ObsDocumentApplicationTest.testMainClass(ObsDocumentApplicationTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
Solution
There's little value in writing a unit test for your Spring Boot entry-point class ObsDocumentApplication
as you end up with almost an exact copy of your implementation.
Such tests can only verify that your mocking setup matches your implementation. Any change to your implementation will most probably fail the unit test as the stubbing setup needs to be adjusted.
A better approach is to write an integration test that makes sure your Spring ApplicationContext
can launch (which will implicitly verify your ObsDocumentApplication
).
You can use the @SpringBootTest
annotation for this purpose.
Answered By - rieckpil
Answer Checked By - Gilberto Lyons (JavaFixing Admin)