我在应用程序中有一组控制器,注释类为@ControllerAdvice
,它设置了在这些控制器中使用的某些数据元素。我正在使用Spring MVC 3.2
并为这些控制器提供Junits。当我运行Junit时,如果我在Tomcat
中部署应用程序并通过浏览器提交请求,则控件不会去ControllerAdvice
类,它可以正常工作。Spring MVC控制器单元测试不调用@ControllerAdvice
有什么想法吗?
我在应用程序中有一组控制器,注释类为@ControllerAdvice
,它设置了在这些控制器中使用的某些数据元素。我正在使用Spring MVC 3.2
并为这些控制器提供Junits。当我运行Junit时,如果我在Tomcat
中部署应用程序并通过浏览器提交请求,则控件不会去ControllerAdvice
类,它可以正常工作。Spring MVC控制器单元测试不调用@ControllerAdvice
有什么想法吗?
您需要提供更多信息,并且可能需要一些实际的代码和/或配置文件,然后才能得到特定的答案。这就是说,基于你提供的一点点,这听起来像注释的bean没有被加载。
尝试将以下内容添加到您的测试applicationContext.xml(或等效的弹簧配置文件,如果使用的话)。
<context:component-scan base-package="com.example.path.to.package" />
或者,您可能需要为“手动”的包括你的测试类之前以下注释加载测试中的语境:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
祝你好运!
我一直在同一件事上挣扎了很长时间。多挖掘后,最好的参考就是Spring文档:
总之,如果你只是测试控制器及其方法,那么你可以使用“standaloneSetup”方法,它创建了一个简单的Spring MVC配置。这将而不是包括您使用@ControllerAdvice注释的错误处理程序。试图测试标注有@ControllerAdvice
ExceptionHandler
当
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class AccountTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Autowired
private AccountService accountService;
// ...
}
您仍然需要初始化mockMvc,这在以上示例中未显示: @Before public void setUp(){ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } – 2015-08-05 13:59:34
您可以使用.setControllerAdvice(xxx)和StandaloneMockMvcBuilder来注入ControllerAdvice bean – frno 2016-09-23 15:21:09
我有类似的问题:
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}
// ...
要建立一个更加完整的Spring MVC配置是确实包含您的错误处理程序,你应该使用下面的设置。在我的情况下,我必须添加@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
配置我的测试通过。
谢谢,您的配置工程很棒!我会奖励赏金! – balteo 2013-09-20 09:56:43
@EnableWebMvc缺席是问题,谢谢。 – raonirenosto 2014-03-23 15:53:11
java.lang.IllegalStateException:无法加载ApplicationContext :( – ptimson 2016-08-04 15:46:11
假设你有@ControllerAdvice注解的类MyControllerAdvice,它有@ExceptionHandler注解的方法。对于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;
}
感谢,伟大的工程 – 2014-02-10 15:35:09
按预期工作,谢谢! – aksamit 2014-02-28 12:43:18
这不适用于我使用异步请求处理 – hvgotcodes 2014-10-22 19:55:21
@tunguski示例代码的作品,但它支付了解事情如何工作。这只是一种设置方法。
@EnableWebMvc
相当于一个Spring配置文件
<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" />
后使用@ eugene-to和另一个类似的答案here我发现了限制并在Spring上提出了一个问题:https://jira.spring.io/browse/SPR-12751
因此,Spring测试引入了在4.2中在构建器中注册@ControllerAdvice
类的能力。如果您使用Spring Boot那么您将需要1.3.0或更高版本。
通过这种改进,如果你使用的是独立安装程序,那么你可以设置一个或多个ControllerAdvice
情况下,像这样:
mockMvc = MockMvcBuilders.standaloneSetup(yourController)
.setControllerAdvice(new YourControllerAdvice())
.build();
注:名称setControllerAdvice()
可能不会让它马上显而易见的,但你可以通过它有很多实例,因为它有一个var-args签名。
太好了。有用。感谢 – 2016-06-13 10:39:11
这应该是公认的答案 – frno 2016-09-23 15:24:03
我添加的东西放入系统,像我一样,谁被弹簧验证上面的伎俩恼火: this.mockMvc = MockMvcBuilders.standaloneSetup(yourController) .setValidator(模拟( Validator.class)) .setControllerAdvice(new CaissierExceptionHandler()) .build(); – 2017-08-28 17:45:50
这是为我工作
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();
}
}
什么版本的弹簧引导可以使用?与1.5.6这个代码永远不会调用我的controlleradvice – 2017-09-18 05:01:35
这将是明显的最小的解决方案,但不起作用.. – Dudelilama 2018-02-19 17:18:23
我遇到过这个问题,而与spock(常规)写入控制器的测试。我的测试类最初是这样写的:
@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被忽略。将代码更改为Autowire mock修复了问题。
@AutoConfigureMockMvc(secure = false)
@SpringBootTest
@Category(RestTest)
class FooControllerTest extends Specification {
@AutowiredMock
FooService FooService
@Autowired
MockMvc mockMvc
欣赏此更新。我遇到类似的问题,@ControllerAdvice类中的@ExceptionHandler(Exception.class)注释方法不通过单元测试 - webAppContextSetup(wac).build()调用。在部署为webapp时调用ExceptionHandler注释的方法。 – kctang 2013-07-29 16:37:06