JUnit断言错误:预期FileNotFoundException未抛出,求排查
JUnit/Mockito测试未触发预期异常的问题排查与修复
问题梳理
你想测试getObj方法在目标路径是目录时抛出FileNotFoundException,但写的测试代码没触发预期异常,报错提示没捕获到该异常。我帮你分析下问题所在,再给出修正方案。
核心错误点
你的测试代码有三个关键问题:
- 根本没调用被测试的
getObj方法:测试里只配置了Mock的返回值,但从来没执行client.getObj(...),自然不会触发异常逻辑。 - Mock方法名不匹配:原方法里调用的是
memoryCache.getStatus(p.toString()),但你的测试里写的是when(memoryCache.getFileStatus(path.toString())).thenReturn(fileStatus);——方法名差了个File,导致Mock完全不生效,实际运行时status会是null,走getStatus(hName, p, "getObj")的分支,而这个分支你没Mock,所以根本到不了判断目录的逻辑。 - 被测试类没注入Mock对象:你Mock了
MemoryCache和FileStatus,但没把Mock的memoryCache给到被测试的类(假设是Client)实例,导致实际运行时用的是真实的MemoryCache,不是你配置的Mock。
修正后的完整测试代码
假设你的被测试类是Client,我给你写了修正后的代码,注释里标了关键改进点:
import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import static org.mockito.Mockito.when; public class ClientTest { // 用MockitoRule自动初始化Mock,比手动mock更简洁 @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Rule public final ExpectedException exception = ExpectedException.none(); @Mock private MemoryCache memoryCache; @Mock private FileStatus fileStatus; // 初始化被测试类,把Mock的memoryCache注入进去 private Client client = new Client(memoryCache); // 如果是Spring环境也可以用@Autowired配合@MockBean @Test public void getObj_WhenPathIsDirectory_ThrowsFileNotFoundException() throws Exception { // 准备测试参数 Path path = Paths.get("xyz://aa-bb-cc/data7-1-23-a.txt"); String hName = "test-h-name"; // 随便填个测试用的hName值 // 修正Mock方法名,和原方法的memoryCache.getStatus完全对应 when(memoryCache.getStatus(path.toString())).thenReturn(fileStatus); // 配置FileStatus为目录 when(fileStatus.isDirectory()).thenReturn(true); // 预期抛出的异常,还可以验证异常消息更严谨 exception.expect(FileNotFoundException.class); exception.expectMessage("Can't open " + path + " because it is a directory"); // 关键!一定要调用被测试方法,才会触发异常逻辑 client.getObj(hName, path); } }
额外注意事项
- 如果你的
Client类里memoryCache是私有成员,没有构造函数或setter注入,可以用Spring的ReflectionTestUtils.setField(client, "memoryCache", memoryCache);来设置私有字段;如果用PowerMock的话也有对应的字段设置方法。 - 看你原方法里抛出异常时写的是
path,但方法参数是p,这里应该是笔误吧?应该改成throw new FileNotFoundException("Can't open " + p + " because it is a directory");,不然会编译报错。
内容的提问来源于stack exchange,提问作者pac
相关产品推荐
相关产品推荐

