我在應用程序中有一組控制器,註釋類爲@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