web-dev-qa-db-ja.com

Spring Bootテストクラスで@WebMvcTestアノテーションを使用するとエラーが発生する

here で説明されている「Spring MVCスライスのテスト」セクションに従って、Spring MVCコントローラーのテストクラスを作成しました。クラスは次のようになります。

@RunWith(SpringRunner.class)
@WebMvcTest(controllers=OurController.class)
public class OurControllerTest {
    @Autowired
    private MockMvc mvc;

    @MockBean
    private OurRepository ourRepository;

    @Test
    public void testGetStuff() {
        // code removed
    }
}

実行すると、次のエラーが発生しました。

MockHttpServletResponse:
           Status = 401
    Error message = null
          Headers = {Cache-Control=[no-store], Pragma=[no-cache], WWW-Authenticate=[Bearer realm="oauth2-resource", error="unauthorized", error_description="Full authentication is required to access this resource"], Content-Type=[application/json;charset=UTF-8], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], X-Frame-Options=[DENY]}
     Content type = application/json;charset=UTF-8
             Body = {"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Java.lang.AssertionError: Status 
Expected :200
Actual   :401
 <Click to see difference>


    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.Java:54)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.Java:81)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.Java:664)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.Java:171)
    at com.ourcompany.mpt.api.repository.controllers.rest.our.OurControllerTest.testGetStuff(OurControllerTest.Java:95)
    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:498)
    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.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:75)
[rest of stack trace removed]

「このリソースにアクセスするには完全な認証が必要です」というエラーが表示されます here といくつかの回避策を示しています。テストクラスの注釈を次のように変更してみました。

@RunWith(SpringRunner.class)
@WebMvcTest(controllers=OurController.class, includeFilters = @ComponentScan.Filter(classes=EnableWebSecurity.class))

次に、次のエラーが発生しました:

2016-12-19 15:43:59.218 ERROR 91076 --- [           main] c.o.m.u.c.error.ErrorHandlerController   : Access is denied

org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.Java:84) ~[spring-security-core-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.Java:233) ~[spring-security-core-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.Java:65) ~[spring-security-core-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.Java:655) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at com.ourcompany.mpt.api.controllers.rest.our.OurController$$EnhancerBySpringCGLIB$$54993f0e.getStuff(<generated>) ~[classes/:na]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_74]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_74]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_74]
    at Java.lang.reflect.Method.invoke(Method.Java:498) ~[na:1.8.0_74]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.Java:221) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:136) ~[spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:114) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.Java:827) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:738) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:85) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:963) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:897) ~[spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:970) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:861) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:622) ~[Tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:846) [spring-webmvc-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.Java:65) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:729) ~[Tomcat-embed-core-8.5.5.jar:8.5.5]
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.Java:167) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:317) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:127) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:91) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:115) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:137) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.Java:111) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:169) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:63) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.Java:176) [spring-security-oauth2-2.0.11.RELEASE.jar:na]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:121) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.Java:66) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:105) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:56) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:331) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:214) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:177) [spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.Java:99) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.Java:89) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:134) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.Java:155) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
    at com.ourcompany.mpt.api.repository.controllers.rest.our.OurControllerTest.testGetStuff(OurControllerTest.Java:94) [test-classes/:na]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_74]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62) ~[na:1.8.0_74]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.8.0_74]
    at Java.lang.reflect.Method.invoke(Method.Java:498) ~[na:1.8.0_74]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.Java:50) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:12) [junit-4.12.jar:4.12]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.Java:47) [junit-4.12.jar:4.12]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.Java:17) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:75) [spring-test-4.3.3.RELEASE.jar:4.3.3.RELEASE]
[rest of stack trace removed]

2016-12-19 15:43:59.327  WARN 91076 --- [           main] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.security.access.AccessDeniedException: Access is denied

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /path/stuff
       Parameters = {}
          Headers = {}

Handler:
             Type = com.ourcompany.mpt.api.controllers.rest.our.OurController
           Method = public Java.util.List<com.ourcompany.mpt.api.domain.our.Our> com.ourcompany.mpt.api.controllers.rest.our.OurController.getStuff()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.security.access.AccessDeniedException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 500
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[SAMEORIGIN]}
     Content type = application/json;charset=UTF-8
             Body = {"error":"org.springframework.security.access.AccessDeniedException","description":"Access is denied","details":[]}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Java.lang.AssertionError: Status 
Expected :200
Actual   :500
 <Click to see difference>


    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.Java:54)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.Java:81)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.Java:664)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.Java:171)
    at com.ourcompany.mpt.api.repository.controllers.rest.our.OurControllerTest.testGetStuff(OurControllerTest.Java:95)
    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:498)
    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.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:75)
[rest of stack trace removed]

次に、テストクラスのアノテーションを次のように変更して、他の回避策を試しました。

@RunWith(SpringRunner.class)
@WebMvcTest(controllers=OurController.class, secure=false)

次に、次のエラーが発生しました:

Java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.Java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.Java:83)
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.Java:47)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.Java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.Java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.Java:287)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.Java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:94)
    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:191)
    at org.junit.runners.Suite.runChild(Suite.Java:128)
    at org.junit.runners.Suite.runChild(Suite.Java:27)
    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.junit.runners.ParentRunner.run(ParentRunner.Java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.Java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.Java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.Java:84)
    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:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:147)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Unsatisfied dependency expressed through method 'setObjectPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [org.springframework.security.config.annotation.ObjectPostProcessor<Java.lang.Object>]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.Java:648)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.Java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:349)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1219)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:751)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:541)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:761)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.Java:371)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:315)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.Java:111)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.Java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.Java:116)
    ... 36 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [org.springframework.security.config.annotation.ObjectPostProcessor<Java.lang.Object>]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.Java:1463)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.Java:1094)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.Java:1056)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.Java:640)
    ... 54 more

次に、@ AutoConfigureMockMvcアノテーションを使用して「このリソースにアクセスするには完全な認証が必要です」というエラーを解決することを提案する別の page を見つけたため、アノテーションを次のように変更しました。

@RunWith(SpringRunner.class)
@WebMvcTest(controllers=OurController.class)
@AutoConfigureMockMvc(secure=false)

しかし、それは以前のエラーと同じ「依存関係[org.springframework.security.config.annotation.ObjectPostProcessor]に適格なBeanが見つかりません:少なくとも1つのBeanがオートワイヤー候補として適格であると期待されていました」をもたらしました。私はその記事の著者にもメールを送り、彼はこのエラーを見たことがないと答えました。

@WebMvcTestアノテーションが機能しない理由を誰かが説明できますか?

11
pacoverflow

プロジェクトを見て、@ ComponentScanアノテーションがないことを確認します。私はあなたと同じようにそれと@WebMvcTestに問題がありました。私は私のように働いています:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = { SomeEntityController.class }, secure = false)
public class SomeEntityControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private SomeEntityService someEntityService;

    private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

    @Before
    public void setup() {

        List<SomeEntity> someEntitys = new ArrayList<>();
        SomeEntity someEntity = new SomeEntity();
        someEntity.setId(new Long(1));

        someEntitys.add(someEntity);

        when(someEntityService.findAll()).thenReturn(someEntitys);
    }

    @Test
    public void findAll() throws Exception {

        ResultActions actions = mockMvc.perform(get("/someEntity/findAll"));

        actions.andExpect(status().isOk()).andExpect(content().contentType(contentType));
    }
}

@RestController
@RequestMapping("/someEntity")
public class SomeEntityController {

    @Autowired
    private SomeEntityService someEntityService;

    @GetMapping(value = "/findAll")
    public List<SomeEntity> findAll() { 
        return someEntityService.findAll();
    }

}

@SpringBootApplication
public class SomeEntityApplication {
    public static void main(String[] args) {
        SpringApplication.run(SomeEntityApplication.class, args);
    }
}
4
Hinotori

@WebMvcTest#secureプロパティは、デフォルトではtrueです。テストの依存関係としてspring-security-testがある場合、テスト中にSpringのセキュリティが有効になります(WebMvcTest#securefalseに設定することで、これをオフにできます)。ただし、コントローラーがAuthenticationまたはそのプリンシパルを使用している場合、テストに失敗する可能性があります。

したがって、@org.springframework.security.test.context.support.WithMockUserを使用して、ユーザー名userおよびパスワードpasswordで認証済みユーザーを作成できます。そうすることで、認証が原因でテストが失敗することはなくなります(ただし、承認が必要になる場合があります)。

テストに関する春のドキュメント here をご覧になることをお勧めします。

3
Sarah Cassar