JUnit测试中如何向Mockito的when()方法传入测试类创建的File实例
问题根因
- 你创建的
FileUtilsmock实例并未被Core类使用:Core类中调用的是FileUtils.readFileToString静态方法,而非你mock出来的f实例的实例方法。静态方法不属于实例对象,普通Mockito默认不支持对静态方法的mock,这是你抛出MissingMethodInvocationException的直接原因。 Core类的文件路径硬编码为固定值Some file name,你在测试类中创建的myFile.txt和业务逻辑要读取的文件没有关联,就算mock问题修复,逻辑也无法对齐。
解决方案
方案1:重构Core类实现可测试性(推荐)
通过Spring配置注入文件名,避免硬编码,直接使用真实文件测试无需mock:
// 改造后的Core类 public class Core { // 文件名支持配置注入,保留原有默认值 @Value("${core.file-name:Some file name}") private String fileName; @Bean public SomeObject obj() throws IOException { String r = FileUtils.readFileToString(new File(fileName)); // 补充原有构造SomeObject的逻辑 } }
// 改造后的测试类 @RunWith(SpringRunner.class) @ContextConfiguration(classes = Core.class) // 注入测试用文件名,和你@Before创建的文件对应 @TestPropertySource(properties = "core.file-name=myFile.txt") public class CoreTest extends TestCase { File file ; @Autowired private Core core; @Before public void init() throws IOException { file = new File("myFile.txt"); file.createNewFile(); // 直接写入测试用的文件内容,不需要mock FileUtils.writeStringToFile(file, "测试用的返回字符串"); } @After public void cleanUp() { file.delete(); } @Test public void testFunction() { try { SomeObject o = core.obj(); assertNotNull(o); // 可补充其他断言验证返回结果符合预期 } catch (Exception e) { e.printStackTrace(); } } }
方案2:不修改Core类,使用Mockito静态mock能力
如果无法修改Core类的业务代码,可以引入Mockito的静态mock能力解决:
- 首先在测试依赖中添加
mockito-inline(基础的mockito-core不支持静态mock),Maven依赖示例:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>和你现有Mockito版本一致即可</version> <scope>test</scope> </dependency>
- 改造后的测试代码:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = Core.class) public class CoreTest extends TestCase { @Autowired private Core core; @Test public void testFunction() { // 用try-with-resources限定静态mock的作用域 try (MockedStatic<FileUtils> mockedFileUtils = Mockito.mockStatic(FileUtils.class)) { // 设定静态方法的返回值,可匹配任意File或者指定文件名的File mockedFileUtils.when(() -> FileUtils.readFileToString(Mockito.any(File.class))) .thenReturn("测试用的返回字符串"); SomeObject o = core.obj(); assertNotNull(o); } catch (Exception e) { e.printStackTrace(); } } }
原有代码其他需要修正的问题
- 测试中手动
new Core(),如果Core作为Spring配置类使用,建议直接从Spring容器注入实例,避免手动实例化导致的Spring注解不生效问题。 - 代码中
str、obj变量未定义,会触发编译错误,需要补充对应的变量定义。 - @Before创建的真实File和后续mock的File逻辑冲突,没有被实际使用,可以删除冗余的mock File代码。
内容的提问来源于stack exchange,提问作者Akanksha_p
相关产品推荐
相关产品推荐

