Java 我应该对哪些方法进行JUnit测试-如何模拟具有许多依赖项的方法
我是JUnit新手,不知道哪些方法应该有测试,哪些不应该。以以下为例:Java 我应该对哪些方法进行JUnit测试-如何模拟具有许多依赖项的方法,java,unit-testing,junit,mocking,mockito,Java,Unit Testing,Junit,Mocking,Mockito,我是JUnit新手,不知道哪些方法应该有测试,哪些不应该。以以下为例: public List<Site> getSites(String user) { SiteDao dao = new SiteDaoImpl(); List<Site> siteList = new ArrayList<Site>(); ServiceRequest rq = new ServiceRequest(); rq.setUser(user);
public List<Site> getSites(String user)
{
SiteDao dao = new SiteDaoImpl();
List<Site> siteList = new ArrayList<Site>();
ServiceRequest rq = new ServiceRequest();
rq.setUser(user);
try
{
ServiceResponse response = siteDAO.getReponse(rq);
List<String> siteNums = response.getSiteNums();
if (siteNums != null && !siteNums.isEmpty())
{
List<DbModelSite> siteInfo = dao.getSiteInfo(siteNums);
if (siteInfo != null && !siteInfo.isEmpty())
{
siteList = SiteMapper.mapSites(siteInfo);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return siteList;
}
public static List<Site> mapSites(List<DbModelSite> siteInfo)
{
List<Site> siteList = null;
if (siteInfo != null && !siteInfo.isEmpty())
{
siteList = new ArrayList<Site>();
for (DbModelSite temp : siteInfo)
{
Site currSite = mapSite(temp);
siteList.add(currSite);
}
}
return siteList;
}
public static Site mapSite(DbModelSite site)
{
Site mappedSite = null;
if (site != null)
{
mappedSite = new Site();
mappedSite.setSiteNum(site.getSiteNum());
mappedSite.setSpace(site.getSpace());
mappedSite.setIndicator("Y");
}
return mappedSite;
}
公共列表获取站点(字符串用户)
{
SiteDao=newsitedaoimpl();
List siteList=new ArrayList();
ServiceRequest rq=新的ServiceRequest();
rq.setUser(用户);
尝试
{
ServiceResponse=siteDAO.getResponse(rq);
List siteNums=response.getSiteNums();
if(siteNums!=null&&!siteNums.isEmpty())
{
List siteInfo=dao.getSiteInfo(siteNums);
if(siteInfo!=null&&!siteInfo.isEmpty())
{
siteList=SiteMapper.mapSites(siteInfo);
}
}
}
捕获(例外e)
{
e、 printStackTrace();
}
返回站点列表;
}
公共静态列表地图站点(列表站点信息)
{
List siteList=null;
if(siteInfo!=null&&!siteInfo.isEmpty())
{
siteList=新的ArrayList();
对于(DbModelSite temp:siteInfo)
{
现场电流现场=地图现场(温度);
站点列表。添加(当前站点);
}
}
返回站点列表;
}
公共静态站点mapSite(DbModelSite站点)
{
Site mappedSite=null;
如果(站点!=null)
{
mappedSite=新站点();
setSiteNum(site.getSiteNum());
setSpace(site.getSpace());
mappedSite.setIndicator(“Y”);
}
返回mappedSite;
}
为mapSite()
和mapSite()
方法提出一个单元测试是非常简单的,但是我遇到的问题是getSites()
方法。对这个方法进行单元测试有意义吗?如果是这样,我将如何着手这样做?这似乎需要相当多的模拟,而且由于我对JUnit非常陌生,我还没有弄清楚如何模拟所有这些对象
所以我的问题有两个:
是的,测试这种方法是有意义的 能够测试它的第一件事是使用依赖项注入。如果该方法使用new创建自己的SiteDao实例,则无法告诉该方法使用另一个模拟SiteDao实例 所以,请阅读依赖注入,并使用它。基本上,它归结为
public class MyService {
private SiteDao siteDao;
public MyService(SiteDao siteDao) {
this.siteDao = siteDao;
}
// use the siteDao passed when constructing the object, instead of constructing it
}
这样,在测试您的服务时,您可以
SiteDao mockSiteDao = mock(SiteDao.class);
SiteService service = new SiteService(mockSiteDao);
这里有一条建议与您的问题没有直接关系,但会使您的代码更简单,因此也更易于测试:
数量,并且您也将有更少的分支需要测试
请注意,所有sane库(JDK方法、JPA等)都遵循这些原则。例如,JPA查询永远不会返回空列表
此外,不要通过打印堆栈跟踪并返回空列表来吞咽异常,就好像没有发生什么不好的事情一样。让异常传播,以便您可以注意到并修复错误
试想一下,这种方法是一种返回医学分析系统发现的癌症肿瘤数量的方法。你真的想让系统告诉你,你的健康状况很好,而系统实际上由于一个异常而无法完成它的工作吗?我真的更喜欢系统说“我出故障了,请使用另一台机器来确定。”是的,测试这种方法是有意义的
能够测试它的第一件事是使用依赖项注入。如果该方法使用new创建自己的SiteDao实例,则无法告诉该方法使用另一个模拟SiteDao实例
所以,请阅读依赖注入,并使用它。基本上,它归结为
public class MyService {
private SiteDao siteDao;
public MyService(SiteDao siteDao) {
this.siteDao = siteDao;
}
// use the siteDao passed when constructing the object, instead of constructing it
}
这样,在测试您的服务时,您可以
SiteDao mockSiteDao = mock(SiteDao.class);
SiteService service = new SiteService(mockSiteDao);
这里有一条建议与您的问题没有直接关系,但会使您的代码更简单,因此也更易于测试:
从不从返回集合的方法返回null。返回一个空集合以表示“无元素”
通常,不要接受null作为有效的方法参数值,特别是当参数是集合时
1和2的推论:通过遵循这些原则,您永远不需要检查集合是否为null或空。直接用就行了李>
这将减少(siteNums!=null&&!siteNums.isEmpty())
使代码混乱的数量,并且您也将有更少的分支需要测试
请注意,所有sane库(JDK方法、JPA等)都遵循这些原则。例如,JPA查询永远不会返回空列表
此外,不要通过打印堆栈跟踪并返回空列表来吞咽异常,就好像没有发生什么不好的事情一样。让异常传播,以便您可以注意到并修复错误
试想一下,这种方法是一种返回医学分析系统发现的癌症肿瘤数量的方法。你真的想让系统告诉你,你的健康状况很好,而系统实际上由于一个异常而无法完成它的工作吗?我真的希望系统说“我出故障了,请使用另一台机器来确保”。单元测试的思想是确保每个“单元”(通常是一种方法)都可以单独测试,这样您就可以测试给定输入的预期输出,从而回答您的问题: