java - 使用 Mockito 模拟助手类

标签 java unit-testing mockito

我有一个带有公共(public)方法的普通帮助程序类,我在服务级别类中使用它。当我为服务类编写测试并尝试为其中一个方法模拟此帮助程序类时,它会进入方法内部并运行每一行。由于此方法内的代码更复杂,我想用方法模拟辅助类,这样我就不必关心辅助类方法内的每个细节。

服务等级

class HistoryServiceImpl implements CaseHistory {
  @Override
  public List<CaseHistoryDto> getCaseHistory(Individual member, Individual provider) {
    MemberUtil memberUtil = new MemberUtil();
    List<CaseHistoryDto> caseHistoryDtoList = new ArrayList<CaseHistoryDto>();
    List<CaseHistory> caseHistoryList = caseDetailDao.fetchCaseHistory(member.getId(), provider.getId());
    for(CaseHistory caseHistory : caseHistoryList) {
        CaseHistoryDto caseHistoryDto = new CaseHistoryDto();
        caseHistoryDto.setMemberInfo(memberUtil.getMemberInfo(member, caseHistory.getCreateDate()));
        caseHistoryDtoList.add(caseHistoryDto);
    }
    return caseHistoryDtoList;
  }
}

测试类

Class HistoryServiceTest {
  @Mock MemberUtil memberUtil;
  @InjectMocks private HistoryServiceImpl historyServiceImpl = new HistoryServiceImpl();

  @Test
  public void testGetCaseHistory() {
    //why this line going inside real method and executing all lines?
    when(memberUtil.getMemberInfo(any(Individual.class), any(Date.class))).thenReturn(member);
  }
}

最佳答案

您的测试用例运行“真实”方法中的所有行的原因是因为您的模拟对象从未在任何地方使用。

如前所述,您无法在 HistoryServiceImpl 中模拟 MemberUtil,因为您是在 getCaseHistory() 方法中手动实例化它。您需要使 getCaseHistory() 从其他地方获取其 MemberUtil,以便您可以在测试类中注入(inject)模拟版本。

最简单的解决方案是将您的 MemberUtil 定义为成员变量,以便 @InjectMocks注解可以覆盖默认值:

class HistoryServiceImpl implements CaseHistory {
    MemberUtil memberUtil = new MemberUtil();

    @Override
    public List<CaseHistoryDto> getCaseHistory(Individual member, Individual provider) {
        ...
    }
}

或者,您可以让 HistoryServiceImpl 在其构造函数中或通过 setter 方法接受外部提供的 MemberUtil。然后,您可以轻松地在测试类中传递模拟版本。

通常,实用程序类是无状态的,因此另一种可能的解决方案是转换 MemberUtil 使其所有方法都是静态的。然后你可以使用类似PowerMock的东西模拟您的静态方法。

关于java - 使用 Mockito 模拟助手类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27236801/

相关文章:

java - 我在 JEE 套接字项目 SLF4J : Failed to load class "org.slf4j.impl.StaticLoggerBinder" 中遇到错误

c# - 我应该如何用最小起订量模拟这个抽象类?

c - 为什么我们要将单元测试文件与源文件分开?

unit-testing - 通过AutoFixture创建TestClass时如何在某些属性上固定范围

unit-testing - 使用 Mockito 模拟挂起函数返回 null

java - 如何正确确定用户是否使用时间顺时针或逆时针拖动我的圆轮 slider ?

java - 如何检查字符串的索引是否等于字符?

java - Spring Amqp 在 springframework RetryCallback 类中有 NoClassDefFoundError

java - Spring数据存储库在测试用例类中未使用@Mock注入(inject)返回null?

java - 模拟服务/ Controller 时,Mockito返回空指针