Use real instances in tests with webflux - mongodb

Hi I try to create a tests for my projeto use only real instances but I getting a follow error:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userQueryService': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'br.com.study.reactivecalendar.domain.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953)
at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
... 86 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'br.com.study.reactivecalendar.domain.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1799)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1355)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 104 more
I know this error is because my test configuration not solved my repository. I want to use web client to ping in my controller
#ActiveProfiles("test")
#ContextConfiguration(classes = {ReactiveCalendarApplication.class, UserMapperImpl.class, UserQueryService.class,
UserService.class, UserRepository.class})
#WebFluxTest({UserController.class, UserRepository.class})
#AutoConfigureDataMongo
#EnableReactiveMongoRepositories
#ExtendWith(SpringExtension.class)
#EnableAutoConfiguration
public class UserControllerInsertTest {
#Autowired
private UserRepository userRepository;
#Autowired
private ApplicationContext applicationContext;
private RequestBuilder<UserSingleResponse> requestBuilder; // this class I create to build requests using WebTestClient
#BeforeEach
void setup(){
requestBuilder = userResponseRequestBuilder(applicationContext, "/users");
}
#Test
void saveTest(){
var request = UserRequestFactoryBot.builder().build();
requestBuilder.withUri(UriBuilder::build)
.withBody(request)
.generateRequestWithSimpleBody()
.doPost()
.isHttpStatusIsCreated()
.assertBody(response -> {
assertThat(response).isNotNull();
assertThat(response).hasNoNullFieldsOrProperties();
assertThat(response.getId()).containsPattern(MONGOID_REGEX);
assertThat(response.getName()).isEqualTo(request.getName());
assertThat(response.getEmail()).isEqualTo(request.getEmail());
});
}
}
to explain about my dependencies:
UserController (#Controller) needs UserMapper, UserService and UserQuery service.
UserService (#Service) needs UserMapper, UserQueryService and UserRepository.
UserQueryService (#Service) needs UserRepository.
UserRepository (#Repository) needs nothing and extends ReactiveMongoRepository
UserMapper needs noting, it is a interface used by mapstruct.
How can I configure my test to solve all dependencies and use all real instances in my test in SpringWebFlux

I solved my problem, follow my configurations:
My test class to verify controller I use a follow annotations
#ActiveProfiles("test")
#ContextConfiguration(classes = {ReactiveCalendarApplication.class, UserMapperImpl.class, UserQueryService.class,
UserService.class, UserRepository.class, EmbeddedMongoDbConfig.class})
#WebFluxTest({UserController.class, UserRepository.class})
#AutoConfigureDataMongo
#ExtendWith({SpringExtension.class})
public class UserControllerDeleteTest {
// my test code
}
My Database Embedded configuration:
#Slf4j
#TestConfiguration
#EnableReactiveMongoRepositories(basePackageClasses = UserRepository.class)
#AllArgsConstructor
public class EmbeddedMongoDbConfig extends AbstractReactiveMongoConfiguration {
private final Environment environment;
#Bean
public MongoClient mongoClient() {
return MongoClients.create();
}
#Override
protected String getDatabaseName() {
return "test";
}
#Bean
ReactiveMongoTemplate reactiveMongoTemplate() {
return new ReactiveMongoTemplate(mongoClient(), getDatabaseName());
}
//optinal configuration, I use because I have custom converters
//for to use OffsetDateTime in my project
#Override
public MongoCustomConversions customConversions() {
List<Converter<? ,?>> converters = new ArrayList<>();
converters.add(new DateToOffsetDateTimeConverter());
converters.add(new OffsetDateTimeToDateConverter());
return new MongoCustomConversions(converters);
}
#Bean
DateTimeProvider dateTimeProvider(){
return new OffsetDateTimeProvider();
}
}
and My application-test.yml
spring:
mongodb:
embedded:
version: 4.0.12
data:
mongodb:
port: 27017
host: localhost
database: test

Related

Register Mock Bean during Integration Testing for SpEL Bean Reference

I am getting the following error while running the test from my spring-boot app. I am using version= 2.3.3.RELEASE of spring-boot-starter-data-mongodb and version=2.2.0 of de.flapdoodle.embed.mongo for integration testing.
org.springframework.expression.spel.SpelEvaluationException: EL1058E: A problem occurred when trying to resolve bean 'gameServiceImpl':'Could not resolve bean reference against BeanFactory'
at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:59)
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:308)
at org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity.getCollection(BasicMongoPersistentEntity.java:129)
at org.springframework.data.mongodb.repository.support.MappingMongoEntityInformation.getCollectionName(MappingMongoEntityInformation.java:97)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.save(SimpleMongoRepository.java:88)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:549)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:155)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy70.save(Unknown Source)
at eatigo.com.webscraper.service.GameServiceImplTest.testSavingSingleEntity(GameServiceImplTest.java:107)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1510)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1510)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: org.springframework.expression.AccessException: Could not resolve bean reference against BeanFactory
at org.springframework.context.expression.BeanFactoryResolver.resolve(BeanFactoryResolver.java:54)
at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:55)
... 89 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'gameServiceImpl' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:816)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1288)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109)
at org.springframework.context.expression.BeanFactoryResolver.resolve(BeanFactoryResolver.java:51)
... 90 more
Below is my simple code implementations
I underdtand that the problem lies in this statement #Document(collection = "#{#gameServiceImpl.getCollectionName()}") because during testing, the SPEL can't find any bean with name='gameServiceImpl' because it has been mocked during testing.
Is there a way to inject a mock bean in the spring container registry for it to be recognized by SPEL?
Is it possible to replace and inject value in the class annotation here #Document(collection = "replace and inject value here") during the initialization of entity class e.g Game game= new Game();
Entity
#Document(collection = "#{#gameServiceImpl.getCollectionName()}")
public class Game {
#Id
private int gameId;
}
Repository
#Repository
public interface GameRepository extends MongoRepository<Game, String> {
}
Service
#Service
public class GameServiceImpl implements GameService {
private GameRepository gameRepository;
private String collectionName;
#Autowired
public GameServiceImpl(GameRepository gameRepository){
this.gameRepository = gameRepository;
}
#Override
public String getCollectionName() {
return collectionName;
}
#Override
public void setCollectionName(String collectionName) {
this.collectionName = collectionName;
}
public Game save(Game game){
return gameRepository.save(game);
}
}
Test
ExtendWith(SpringExtension.class)
#ActiveProfiles("test")
#BootstrapWith(SpringBootTestContextBootstrapper.class)
#SpringBootTest(classes = {MainApplication.class})
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
#DataMongoTest
public class GameServiceImplTest {
#Mock(name = "gameServiceImpl")
private GameServiceImpl gameServiceImpl;
#Autowired
private GameRepository gameRepository;
#Autowired
private MongoTemplate mongoTemplate;
#BeforeEach
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSavingGame(){
Game game= new Game();
String collectionName = "testing";
gameServiceImpl.setCollectionName(collectionName);
when(gameServiceImpl.save(game)).thenReturn(gameRepository.save(game));
when(gameServiceImpl.getCollectionName()).thenReturn(collectionName);
Game result = gameServiceImpl.save(game);
assertThat(result, is(notNullValue()));
assertThat(mongoTemplate.collectionExists(collectionName), is(true));
assertThat(mongoTemplate.findAll(Game.class, collectionName).size(), equalTo(1));
}
}
Thanks to #M. Deinum direction and some help from here, I was able to achieve results with the following modifications.
Test
#ExtendWith(SpringExtension.class)
#ActiveProfiles("test")
#BootstrapWith(SpringBootTestContextBootstrapper.class)
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
#DataMongoTest
public class GameServiceImplTest {
#MockBean(name = "gameServiceImpl")
public GameServiceImpl gameServiceImpl;
#Autowired
private GameRepository gameRepository;
#Autowired
private MongoTemplate mongoTemplate;
#BeforeEach
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSavingSingleEntity(){
Game game = new Game();
String collectionName = "testingCollection";
gameServiceImpl.setCollectionName(collectionName);
when(gameServiceImpl.getCollectionName()).thenReturn(collectionName);
Game result = gameRepository.save(game);
when(gameServiceImpl.save(game)).thenReturn(result);
assertThat(gameServiceImpl.save(game), is(notNullValue()));
assertThat(mongoTemplate.collectionExists(collectionName), is(true));
assertThat(mongoTemplate.findAll(Game.class, collectionName).size(), equalTo(1));
}
}

java.lang.IllegalStateException: Failed to load ApplicationContext error in Spring Boot

I am new to unit testing and I have to test my methods in spring boot.
I created application with Spring Security JWT Authentication + PostgreSQL – RestAPIs SpringBoot + Spring MVC + Spring JPA from this link
then I created controller for users to edit update ect.
My users controller looks like this
#RestController
#RequestMapping("/users")
public class Users {
#Autowired
private UserService userService;
#GetMapping(value = "/*")//can access with this root
#PreAuthorize("hasRole('ADMIN')") //Only admin can view all users' details
public List<User> AllUsers(){
return this.userService.getAllUsers();
}
#GetMapping(value = "/{username}")//can access with this root
public User GetOneUser(#PathVariable(value = "username") String username){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String auth_name = auth.getName(); //get logged in username
if(auth_name.equals(username)||this.userService.isAdmin(auth_name)){//admin and user can see the details
return this.userService.getUser(username);
}
else{
return null;
}
}
#DeleteMapping(value = "/{id}")//can access with this root
#PreAuthorize("hasRole('ADMIN')") //Only admin can delete user
public void DeleteUser(#PathVariable(value = "id") Long id){
this.userService.deleteUser(id);
}
#PostMapping(value = "/{username}")//can access with this root
public User EditUser(#PathVariable(value = "username") String username,#RequestBody SignUpForm user) {//only user can edit
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String auth_name = auth.getName(); //get logged in username
User upUser=null;
if(auth_name.equals(username)){
upUser=this.userService.updateUser(username,user);
}
return upUser;
}
}
then I created UserService like this:
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
PasswordEncoder encoder;
public List<User> getAllUsers(){
// return topics;
List<User> users=new ArrayList<>();
userRepository.findAll().forEach(users::add);
return users;
}
public boolean isAdmin(String username){
boolean flag=false;
if(this.userRepository.existsByUsername(username)){
User user=this.userRepository.findByUsername(username).get();
Role adminRole = roleRepository.findByName(RoleName.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
if(user.getId().equals(adminRole.getId())){
flag=true;
}
}
return flag;
}
public User getUser(String username){
return userRepository.findByUsername(username).orElse(null);
}
public User updateUser(String username, SignUpForm user) {
if(userRepository.existsByUsername(username)) {
User ExistingUser=userRepository.findByUsername(username).get();
if(ExistingUser.getName()!=user.getName()){
ExistingUser.setName(user.getName());
}
if(ExistingUser.getUsername()!=user.getUsername()){
ExistingUser.setUsername(user.getUsername());
}
if(ExistingUser.getPassword()!=user.getPassword()){
ExistingUser.setPassword(encoder.encode(user.getPassword()));
}
if(ExistingUser.getEmail()!=user.getEmail()){
ExistingUser.setEmail(user.getEmail());
}
Set<String> Roles =user.getRole();
Set<Role> roles = new HashSet<>();
Roles.forEach(role -> {
switch(role) {
case "admin":
Role adminRole = roleRepository.findByName(RoleName.ROLE_ADMIN)
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
roles.add(adminRole);
break;
case "pm":
Role pmRole = roleRepository.findByName(RoleName.ROLE_PM)
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
roles.add(pmRole);
break;
default:
Role userRole = roleRepository.findByName(RoleName.ROLE_USER)
.orElseThrow(() -> new RuntimeException("Fail! -> Cause: User Role not find."));
roles.add(userRole);
}
});
if(ExistingUser.getRoles()!=roles){
ExistingUser.setRoles(roles);
}
userRepository.save(ExistingUser);
}
return userRepository.findByUsername(user.getUsername()).get();
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
it works.
But then I created class for testing that tests getUser() method from UserService
#WebMvcTest
#RunWith(SpringRunner.class)
public class UserServiceTest {
#MockBean
UserRepository repository;
#Autowired
UserService userService;
#Test
public void getUserTest(){
User user=this.userService.getUser("arife");
assertThat(user).isNotNull();
}
}
But it gives me error that looks like this:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:95)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
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.factory.UnsatisfiedDependencyException: Error creating bean with name 'authRestAPIs': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'springbootjwtauthenticationpostgresql.springbootjwtauthenticationpostgresql.security.services.UserDetailsServiceImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:598)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:847)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 25 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'springbootjwtauthenticationpostgresql.springbootjwtauthenticationpostgresql.security.services.UserDetailsServiceImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:598)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:376)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:392)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1255)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595)
... 43 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'springbootjwtauthenticationpostgresql.springbootjwtauthenticationpostgresql.security.services.UserDetailsServiceImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1662)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1221)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1175)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:595)
... 65 more
Please can someone help me?
Is pretty hard to follow up your problem if you don't add more details (log trace, code snapshots...)
But maybe you can find this pet project done by me (https://github.com/geeksusma/jwt-rest-controller)
Basically is a RestController which works with JWT.
I hope it could help
Now I wrote like this
#DataJpaTest
#RunWith(SpringRunner.class)
public class UserServiceTest {
#MockBean
UserService userService;
#Test
public void getUserTest(){
assertThat(this.userService.getUser("arife")).isNotNull();
}
}
and then I added new File application-test.properties
#ActiveProfiles("test")
#PostgreSQL
spring.datasource.url=jdbc:postgresql:
spring.datasource.username=
spring.datasource.password=
spring.jpa.generate-ddl=true
now it gives me error
java.lang.AssertionError:
Expecting actual not to be null
at springbootjwtauthenticationpostgresql.springbootjwtauthenticationpostgresql.model.UserServiceTest.getUserTest(UserServiceTest.java:59)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
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)
I think that is not connected to database

ApplicationContext Exception in Test with #WebMvcTest

I Have an Spring Boot Application (1.5.10.RELEASE) which contains a main (SpringBootApplication) like this:
#SpringBootApplication
#Configuration
#EntityScan(basePackages = { "db.modell", "db.modell.base" })
#ComponentScan(basePackages = { "de.gui.test" })
public class SpringBootConsoleApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
}
and two REST controllers like the following:
#RestController
#RequestMapping("/as")
public class AController {
#Autowired
private ARepository aRepository;
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<A>> getAs() {
return new ResponseEntity<>(orgtFarbeRepository.findAll(), HttpStatus.OK);
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<A> getA(#PathVariable long id) {
A a = ARepository.findOne(id);
if (party != null) {
return new ResponseEntity<>(ARepository.findOne(id), HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
}
}
Furthermore I have a single test like this:
#RunWith(SpringRunner.class)
#WebMvcTest(AController.class)
public class AControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private ARepository ARepository;
#Test
public void firstTest() throws Exception {
A a = new aFarbe();
a.set....
when(ARepository.findAll()).thenReturn(Collections.singleton(a));
mvc.perform(
get("/as")
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
)
.andExpect(status().isOk());
}
}
The repositories look like this:
public interface ARepository extends CrudRepository<A, Long>
{
Collection<A> findAll();
}
public interface BRepository extends CrudRepository<B, Long>
{
Collection<B> findAll();
}
A and B them self are JPA annotated classes. The whole application contains access to a database..
Furthermore I have a Service like this:
#Service
public class XService {
private static final Logger LOGGER = LoggerFactory.getLogger(XService.class);
#Autowired
private ARepository aRepository;
#Autowired
private BRepository bRepository;
...
}
The XService is not used via #Autowire or so (Just need to remove that):
So I try to run the AControllerTest I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
.. .. at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'XService': Unsatisfied dependency
expressed through field 'BRepository'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
.. .. at
org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 26 more Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'BRepository' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 44 more
My assumption is that during the test more context is started than it should. The question is how can I prevent that? Which means only to start the context for the AControler and nothing more? I thought that based on the #WebMvcTest(AController.class) it should be limited already which looks like that it was not the case...
The referenced answer does not really answered my question but a in the context a hint gave me the solution. This means in consequence to add the following to my test:
so I have to add #OverrideAutoConfiguration(enabled=true):
#RunWith(SpringRunner.class)
#WebMvcTest(OrgtFarbenController.class)
#OverrideAutoConfiguration(enabled=true)
public class AControllerTest {
...
}

Can't get Feign Client to work for a basic example

Can't get Feign Client to work. First tried with POST. Kept running into errors related to Encoder/Decoder saying type is not right.
Then found an example on github to call simple GET API finally and decided to give it a shot.
Still fails
On Github and online, I am seeing multiple versions of Feign Client
Spring-Cloud, OpenFeign, Netflix.feign having different versions.
Could anyone describe what's the best and stable Feign client one should use for production?
package com.paa.controllers;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#FeignClient (name="test-service",url="https://www.reddit.com/r")
public interface GetFeignClient {
#RequestMapping(method = RequestMethod.GET, value = "/java.json")
public String posts();
}
Controller:
#RestController
#RequestMapping("/some/api")
public class TestWLCController {
#Autowired
private GetFeignClient getFeignClient;
.. some stuff
#RequestMapping(value="/postSomething",method = RequestMethod.POST)
#ApiOperation(value = "Configures something",
notes = "basic rest controller for testing feign")
public ResponseEntity<SomeResponse> feignPost(
UriComponentsBuilder builder,
#ApiParam(name = "myRequest",
value = "request for configuring something",
required = true)
#Valid #RequestBody SomeRequest someRequest) {
String resp = null;
try {
resp = getFeignClient.posts();
} catch (Exception er) {
er.printStackTrace();
}
}
}
Application:
Tried all possible permutations of annotations thinking it would resolve AutoWire stuff but still fails
#Configuration
#ComponentScan
#EnableAutoConfiguration
//#EnableEurekaClient
#EnableFeignClients
//#SpringBootApplication
//#EnableFeignClients
//#EnableFeignClients(basePackages = {"com.paa.xenia.controllers", "com.paa.xenia.services"})
public class ServiceApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(XeniaServiceApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
2016-07-20 18:15:42.406[0;39m [31mERROR[0;39m [35m32749[0;39m
[2m---[0;39m [2m[ main][0;39m
[36mo.s.boot.SpringApplication [0;39m [2m:[0;39m
Application startup failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'testWLCController': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.paa.controllers.GetFeignClient
com.paa.controllers.TestWLCController.gfClient; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'com.aa..controllers.GetFeignClient':
FactoryBean threw exception on object creation; nested exception is
java.lang.NullPointerException at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at
com.paa.ServiceApplication.main(ServiceApplication.java:44) [bin/:na]
Caused by: org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.paa.controllers.GetFeignClient
com.paa.controllers.TestWLCController.gfClient; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'com.paa.controllers.GetFeignClient':
FactoryBean threw exception on object creation; nested exception is
java.lang.NullPointerException at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] ... 17 com.n frames
omitted
I'm not sure if you eventually figured it out yourself, but for the sake of others who might stumble across this thread, below is a working example of what you were trying to do. I'll first point out a few things that are incorrect, or at least, not desired in your code, then show my code that works.
You should try not to use the url attribute. Instead, set up a list of servers using <feign client name>.ribbon.listOfServers in bootstrap.yml (or bootstrap.properties). This allows for client side load balancing because listOfServers can be a comma-separated list.
Using Ribbon for HTTPS connections, you need to specify two things that you don't need for HTTP connections. The port, which is part of the listOfServers and <feign client name>.ribbon.IsSecure: true. Without the port, the connection is made to port 80 and without the IsSecure, HTTP is used.
Testing using curl, I found that Reddit takes a very long time to respond. See this SO post for details of how to break down the total time taken by the request-response cycle.
$ curl -v -H "User-Agent: Mozilla/5.0" -w "#curl-format.txt" -o /dev/null -s "https://www.reddit.com/r/java/top.json?count=1"
{ [2759 bytes data]
* Connection #0 to host www.reddit.com left intact
time_namelookup: 0.527
time_connect: 0.577
time_appconnect: 0.758
time_pretransfer: 0.758
time_redirect: 0.000
time_starttransfer: 11.189
----------
time_total: 11.218
According the Netflix Wiki, the default read and connect timeouts are 3000 milliseconds, so you will always timeout unless you change those.
You may have noticed that I specified a User-Agent header in the curl request. That's because Reddis seems to be very picky about that and if not specified, returns a HTTP 429 "Too many requests" most of the times. They don't return a Retry-After header in the response so there's no telling how long you need to wait before making another request.
Spring Cloud Netflix as well as Netflix Feign is open source, so some (a lot of) patience and debugging skills come really handy.
"Talk is cheap. Show me the code." (Torvalds, Linus (2000-08-25)).
I generated a Gradle app using the excellent Spring Initializr site. Here's a snippet from the build.gradle file.
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-feign')
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.SR3"
}
}
Feign client:
#FeignClient(name = "reddit")
public interface RedditClient {
#RequestMapping(method = GET, value = "/r/java/top.json?count=1",
headers = {USER_AGENT + "=Mozilla/5.0", ACCEPT + "=" + APPLICATION_JSON_VALUE})
public String posts();
}
Boot Application:
#SpringBootApplication
#EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#RestController
static class DemoController {
#Autowired
private RedditClient redditClient;
#GetMapping("/posts")
public String posts() {
return redditClient.posts();
}
}
}
bootstrap.yml:
reddit:
ribbon:
listOfServers: www.reddit.com:443
ConnectTimeout: 20000
ReadTimeout: 20000
IsSecure: true
hystrix.command.default.execution:
timeout.enabled: true
isolation.thread.timeoutInMilliseconds: 50000
Integration test:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTest {
#Autowired
private TestRestTemplate restTemplate;
#Test
public void testGetPosts() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("/posts", String.class);
HttpStatus statusCode = responseEntity.getStatusCode();
assertThat(String.format("Actual status code: %d, reason: %s.",
statusCode.value(), statusCode.getReasonPhrase()),
statusCode.is2xxSuccessful(), equalTo(true));
}
}
Dependencies:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
App:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.test.cloud.bookservice.models.Book;
#SpringBootApplication
#RestController
#RequestMapping("/books")
#EnableFeignClients
public class BookServiceApplication {
Logger logger = LogManager.getLogger(BookServiceApplication.class);
#Autowired
private StoreClient storeClient;
public static void main(String[] args) {
SpringApplication.run(BookServiceApplication.class, args);
}
#GetMapping("/book")
public Book findBook() {
return this.restTemplate.getForObject("http://stores/book", Book.class);
}
#FeignClient(name = "StoreClient", url = "127.0.0.1:8089")
interface StoreClient {
#RequestMapping(method = RequestMethod.GET, value = "/stores/book", consumes = "application/json")
Book getBook();
}
}
Someone was interested to find out how did we do it so posting answer for their benefit.
Parent Module
package com.hitech.module.base;
#EnableFeignClients
public abstract class BaseApplication extends SpringBootServletInitializer {
...
..
}
build.gradle:
buildscript {
ext {
springBootVersion = '1.3.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE")
}
}
...
...
dependencies {
compile('io.springfox:springfox-swagger-ui:2.5.0')
compile('io.springfox:springfox-swagger2:2.5.0')
compile('org.springframework.cloud:spring-cloud-starter-feign')
Child Module
package com.hitech.module.app;
import com.hitech.module.base.BaseApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
#SpringBootApplication(exclude = {MongoDataAutoConfiguration.class, MongoAutoConfiguration.class},
scanBasePackages = {"com.hitech.module.base", "com.hitech.module.app", })
#EnableFeignClients("com.hitech.module.app.clients")
public class MyServiceApplication extends BaseApplication {
private static final Logger LOG = LoggerFactory.getLogger(MyServiceApplication.class);
public static void main(String[] args) {
String s1 = "google";
LOG.info ("=== Started Orchestration Service ===");
SpringApplication.run(MyServiceApplication.class, args);
}
}
bootstrap.yml
feign:
hystrix:
enabled: false
datasource:
audit:
mongodb:
host: localhost
port: 27019
database: audit

$proxy25 error with Spring Service

I have two Service classes which implement the same interface
ServiceClass1
#Service
public class ServiceClass1 implements ItemsService{
#Autowired
Class1DaoImpl class1Dao;
#Transactional
public List<Class1> getAllItems() {
return class1Dao.getAllItems();
}
ServiceClass2
#Service
public class ServiceClass2 implements ItemsService{
#Autowired
Class2DaoImpl class2Dao;
#Transactional
public List<Class2> getAllItems() {
return class2Dao.getAllItems();
}
And this is the controller class
#Controller
public class IndexController {
#Autowired
ServiceClass1 serviceClass1;
#Autowired
ServiceClass1 serviceClass2;
............
.....
}
I got this error when the page was requested
java.lang.IllegalArgumentException: Can not set com.package.ServiceClass1 field com.package.IndexController.serviceClass1 to $Proxy25
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
java.lang.reflect.Field.set(Field.java:657)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:500)
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:609)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:623)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:491)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:432)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
javax.servlet.GenericServlet.init(GenericServlet.java:212)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java:662)
I did some google-ing and can't seem to find any solid answer to why am I getting this error?
You need to autowire against the interface type, not the class type, i.e.
#Autowired
ItemsService serviceClass1;
If you have multiple beans that implement ItemsService, then autowiring isn't really appropriate. Consider using #Resource instead:
#Resource(name="serviceClass1")
ItemsService serviceClass1;
#Resource(name="serviceClass2")
ItemsService serviceClass1;