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

如何用Mockito模拟SimpleDateFormat.parse()抛出异常测试Dao方法

测试Dao中saveTemplate的异常分支:从踩坑到解决

作为Java/Mockito新手,你要验证saveTemplate方法捕获ParseException并抛出SQLException的逻辑,这个场景很常见,我来帮你梳理整个过程:

你的目标场景

先看Dao核心代码里的关键逻辑:

public Template saveTemplate(Template template) throws SQLException { 
    logger.debug("Saving template details into the db ", template.getTemplateName()); 
    SimpleDateFormat dt = new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss"); 
    Long date = 0L; 
    try { 
        date = dt.parse(template.getStartTime()).getTime(); 
    } catch (ParseException e) { 
        throw new SQLException("Error while processing date " + template.getTemplateName()); 
    } 
    // 后续代码...
}

我们需要触发try块里的ParseException,进而验证catch块抛出的SQLException。

你之前踩的坑

1. 用@InjectMocks注入SimpleDateFormat失败

报错信息:

org.mockito.exceptions.base.MockitoException: Cannot instantiate @InjectMocks field named 'simpleDateFormat' of type 'class java.text.SimpleDateFormat'. You haven't provided the instance at field declaration so I tried to construct the instance. However the constructor or the initialization block threw an exception : null

原因很简单:SimpleDateFormat的构造函数必须传入格式字符串参数,Mockito无法自动无参实例化它,所以@InjectMocks在这里行不通。

2. 用@Mock模拟SimpleDateFormat触发参数匹配器错误

报错信息:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here: ...

本质问题是:SimpleDateFormat继承自DateFormat,而DateFormat的parse方法是final方法。Mockito默认不能mock final方法(除非开启Mockito的final方法mock功能),所以你尝试mock它的parse方法时,Mockito无法正确处理,进而抛出参数匹配器的错误提示(这个提示有点误导,但核心是你mock了不能被mock的方法)。

成功的解决方案:让模板返回无效日期字符串

不需要去mockSimpleDateFormat,直接让Template.getStartTime()返回一个无法被解析的日期字符串,这样真实的parse方法就会抛出ParseException,自然触发catch块的SQLException。

你的测试代码已经成功,整理后的版本:

@Test(expected = SQLException.class) 
public void test_save_template_date_parse_error() throws ParseException, SQLException { 
    initMocks(this); 
    // 模拟Template对象,让它返回无效日期
    Template templateMock = Mockito.mock(Template.class); 
    Mockito.when(templateMock.getStartTime()).thenReturn("invalid"); 
    
    // 准备其他依赖(比如jdbcTemplate,根据你的实际情况调整)
    given(jdbcTemplate.getJdbcOperations()).willReturn(jdbcOperations); 
    
    // 调用方法,预期抛出SQLException
    templateDAOImpl.saveTemplate(templateMock); 
}

这个方案的优势:

  • 完全贴合真实代码逻辑,不需要mock底层的日期解析类
  • 代码简洁,容易维护,符合Mockito的测试理念:mock依赖,而不是底层JDK类

内容的提问来源于stack exchange,提问作者JESii

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:07:35