我有一个带有公共(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/