Spring MVC控制器单元测试不是要求@ControllerAdvice(Spring MVC

2019-08-17 10:22发布

我有一组应用程序中的和注解的作为一类控制器的@ControllerAdvice其中建立了在每一个这些控制器的所使用的某些数据元素。 我使用Spring MVC 3.2 ,并有这些控制器Junits。 当我运行JUnit的控制是不会给ControllerAdvice类何在,如果我在部署应用程序正常工作Tomcat ,并通过浏览器提交的请求。

任何想法请?

Answer 1:

使用答案来自@尤金到和其他类似的一个后, 在这里我找到了限制,并在春季提出的一个问题: https://jira.spring.io/browse/SPR-12751

其结果是,Spring的测试推出能够注册@ControllerAdvice 4.2在构建器类。 如果您在使用Spring启动 ,那么你将需要1.3.0或更高版本。

通过这种改进,如果你使用的是独立安装程序,那么你可以设置一个或多个ControllerAdvice情况下,像这样:

mockMvc = MockMvcBuilders.standaloneSetup(yourController)
            .setControllerAdvice(new YourControllerAdvice())
            .build();

注:名称setControllerAdvice()可能不会使它立即显而易见的,但你可以通过很多情况下它,因为它有一个变种- ARGS签名。



Answer 2:

假设你有一个具有与@ExceptionHandler注解的方法@ControllerAdvice注解类MyControllerAdvice。 对于MockMvc您可以轻松地添加这个类作为异常解析器。

@Before
public void beforeTest() {
    MockMvc mockMvc = standaloneSetup(myControllers)
        .setHandlerExceptionResolvers(createExceptionResolver())
        .build();
}

private ExceptionHandlerExceptionResolver createExceptionResolver() {
    ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
        protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
            Method method = new ExceptionHandlerMethodResolver(MyControllerAdvice.class).resolveMethod(exception);
            return new ServletInvocableHandlerMethod(new MyControllerAdvice(), method);
        }
    };
    exceptionResolver.afterPropertiesSet();
    return exceptionResolver;
}


Answer 3:

试图测试,当我有类似的问题ExceptionHandler注释与@ControllerAdvice 。 在我来说,我不得不添加@Configuration与文件@EnableWebMvc注解@ContextConfiguration在测试类。

所以,我的测试是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {
  RestProcessingExceptionHandler.class,
  TestConfiguration.class,
  RestProcessingExceptionThrowingController.class })
public class TestRestProcessingExceptionHandler {


  private MockMvc mockMvc;
  @Autowired
  WebApplicationContext wac;


  @Before
  public void setup() {
    mockMvc = webAppContextSetup(wac).build();
  }


  @Configuration
  // !!! this is very important - conf with this annotation 
  //     must be included in @ContextConfiguration
  @EnableWebMvc
  public static class TestConfiguration { }


  @Controller
  @RequestMapping("/tests")
  public static class RestProcessingExceptionThrowingController {


    @RequestMapping(value = "/exception", method = GET)
    public @ResponseBody String find() {
      throw new RestProcessingException("global_error_test");
    }
  }


  @Test
  public void testHandleException() throws Exception {
    mockMvc.perform(get("/tests/exception"))
        .andExpect(new ResultMatcher() {


          @Override
          public void match(MvcResult result) throws Exception {
            result.getResponse().getContentAsString().contains("global_error_test");
          }
        })
        .andExpect(status().isBadRequest());
  }
}

随着@EnableWebMvc配置我的测试通过。



Answer 4:

我一直在挣扎了同样的事情相当长的一段时间。 多挖掘后,最好的参考就是Spring文档:

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/testing.html#spring-mvc-test-framework

总之,如果你只是测试控制器及其方法,那么你可以使用它创建了一个简单的Spring MVC配置“standaloneSetup”的方法。 这将包括你@ControllerAdvice注释错误处理程序。

private MockMvc mockMvc;

@Before
public void setup() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}

// ...

要创建一个更完整的Spring MVC的配置不会包含你应该使用下面的设置您的错误处理程序:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class AccountTests {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Autowired
    private AccountService accountService;

    // ...

}


Answer 5:

这是为我工作

public class MyGlobalExceptionHandlerTest {

    private MockMvc mockMvc;

    @Mock
    HealthController healthController;

    @BeforeTest
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(healthController).setControllerAdvice(new GlobalExceptionHandler())
            .build();
    }

    @Test(groups = { "services" })
    public void testGlobalExceptionHandlerError() throws Exception {

        Mockito.when(healthController.health()).thenThrow(new RuntimeException("Unexpected Exception"));

        mockMvc.perform(get("/health")).andExpect(status().is(500)).andReturn();

    }

}


Answer 6:

@tunguski示例代码的作品,但它支付了解的东西是如何工作的。 这只是一个设置事情的方式。

@EnableWebMvc相当于一个弹簧配置文件以下

<mvc:annotation-driven />

本质的东西的工作,你需要初始化Spring MVC和加载所有的控制器和bean引用。 所以,下面可能是一个有效的参数设置以及备用

以下是你将如何设置测试类

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath: "classpath:test-context.xml" })
    @WebAppConfiguration    
    public class BaseTest {

        @Autowired
        WebApplicationContext wac;

        private MockMvc mockMvc;

        @Before
        public void setUp()  {
            mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        }
    }

而下面可能是测试spring配置

<mvc:annotation-driven />
<context:component-scan base-package="com.base.package.controllers" />


Answer 7:

您需要提供更多的信息,也许一些实际的代码和/或配置文件,你可以期望具体的答案之前。 这就是说,根据您所提供的一点,这听起来像没有被加载注释豆。

尝试添加下列到测试的applicationContext.xml(或等效弹簧的配置文件,如果你正在使用一个)。

<context:component-scan base-package="com.example.path.to.package" />

或者,您可能需要包括您的测试类之前,下面的注释为“手动”中加载测试中的上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")

祝好运!



Answer 8:

我遇到过这个问题,而与写入控制器测试斯波克 (常规)。 我的测试类原本是这样写的:

@AutoConfigureMockMvc(secure = false)
@SpringBootTest
@Category(RestTest)
class FooControllerTest extends Specification {
  def fooService = Mock(FooService)
  def underTest = new FooController(FooService)
  def mockMvc = MockMvcBuilders.standaloneSetup(underTest).build()
....
}

这导致ControllerAdvice被忽略。 更改代码,自动装配的嘲笑解决了这一问题。

@AutoConfigureMockMvc(secure = false)
@SpringBootTest
@Category(RestTest)
class FooControllerTest extends Specification {

  @AutowiredMock
  FooService FooService

  @Autowired
  MockMvc mockMvc


Answer 9:

我怀疑你需要在测试中使用asyncDispatch; 定期测试框架被打破与异步控制器。

尝试在方法: https://github.com/spring-projects/spring-framework/blob/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests的.java



文章来源: Spring MVC Controllers Unit Test not calling @ControllerAdvice