You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

控制器中的异常在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:55:03