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