我有一个普通的帮助器类,其中包含我在服务级别类中使用的公共方法。当我为服务类编写测试并尝试模拟其中一个方法的辅助类时,它将进入方法并运行每一行。由于此方法中的代码更复杂,我想使用方法来模拟辅助类,这样我就不必处理辅助类方法中的每个细节。
服务类
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);
}
}
答案 0 :(得分:2)
您的测试用例运行&#34; real&#34;中的所有行的原因方法,是因为你的模拟对象永远不会在任何地方使用。
如上所述,您无法在MemberUtil
中模拟HistoryServiceImpl
,因为您是在getCaseHistory()
方法中手动实例化它。您需要让getCaseHistory()
从其他地方获取MemberUtil
,以便您可以在测试类中注入模拟版本。
最简单的解决方案是将MemberUtil
定义为成员变量,以便@InjectMocks
注释可以覆盖默认值:
class HistoryServiceImpl implements CaseHistory {
MemberUtil memberUtil = new MemberUtil();
@Override
public List<CaseHistoryDto> getCaseHistory(Individual member, Individual provider) {
...
}
}
或者,您可以HistoryServiceImpl
在其构造函数中或通过setter方法接受外部提供的MemberUtil
。然后,您可以轻松地在测试类中传入模拟版本。
通常,实用程序类是无状态的,因此另一种可能的解决方案是转换MemberUtil
以使其所有方法都是静态的。然后你可以使用类似PowerMock的东西来模拟你的静态方法。