控制器中的异常在JUnit中未触发,求编写IllegalArgumentException测试用例
嘿,我来帮你搞定这个JUnit测试里触发不了控制器异常的问题!你的核心痛点在于没法让控制器里的IllegalArgumentException在测试中被触发,这大概率是因为你直接在控制器里new了SomeClass实例,导致测试时没法控制它的行为。下面是一步步的解决方案:
解决方案步骤
1. 先重构控制器(关键!)
你当前的控制器直接new SomeClass(),这会让测试无法模拟这个类的方法行为。最好改成构造函数注入,这样测试时可以轻松替换成Mock对象:
@Controller public class ExampleController { private final SomeClass someClass; // 构造函数注入依赖 public ExampleController(SomeClass someClass) { this.someClass = someClass; } @RequestMapping(value = "/samplePage") public ResponseEntity getSampleDetails() { try { Object response = someClass.getData(); return new ResponseEntity<>(response, HttpStatus.OK); } catch(IllegalArgumentException e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } }
2. 编写正确的JUnit测试用例
我们用@WebMvcTest专注测试控制器,结合@MockBean来模拟SomeClass,再用MockMvc发起请求验证结果:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(ExampleController.class) public class ExampleControllerTest { @Autowired private MockMvc mockMvc; @MockBean private SomeClass someClass; @Test public void getSampleDetails_WhenIllegalArgumentThrown_Returns500() throws Exception { // 关键:模拟SomeClass的getData()方法抛出IllegalArgumentException when(someClass.getData()).thenThrow(new IllegalArgumentException("Test exception")); // 发起GET请求,验证返回状态码是500(INTERNAL_SERVER_ERROR) mockMvc.perform(get("/samplePage")) .andExpect(status().isInternalServerError()); } // 可以额外加一个正常场景的测试作为对照 @Test public void getSampleDetails_WhenDataFetched_Returns200() throws Exception { when(someClass.getData()).thenReturn("Sample response data"); mockMvc.perform(get("/samplePage")) .andExpect(status().isOk()); } }
3. 为什么之前的测试没触发异常?
你之前的代码里直接new SomeClass(),这意味着测试时使用的是真实的SomeClass实例,它的getData()方法不会主动抛出异常。通过依赖注入+@MockBean,我们完全控制了SomeClass的行为,让它在测试时抛出我们指定的异常,这样就能进入控制器的catch块了。
小提示
- 如果你用的是JUnit 4,记得在测试类上加上
@RunWith(SpringRunner.class);JUnit 5则不需要,直接用@WebMvcTest就行。 @MockBean会自动把Mock对象注入到控制器中,比手动创建Mock再注入更省心。
内容的提问来源于stack exchange,提问作者harshini kasinadhuni
相关产品推荐
相关产品推荐

