使用模拟对象测试DAO的Mockito方法

3

我想测试这个DAO方法

//in GrabDao.java
public WrapperProject getChildren(Integer entityId, String entityType){

    EntityDao entityDao = new EntityDao();
    UserDao userDao = new UserDao();

    EntityBase entity = entityDao.getEntityById(entityId, entityType);
    Date dateProjet = userDao.getOrganismeFromSession().getExercice().getDateProjet();

    return new Wrapper(dateProjet, entity);
}

这是我目前尝试过的:
    //in GrabDaoTest.java
    Integer paramEntityId = 1; 
    String paramEntityType = "type";

    EntityBase entityBase = Mockito.mock(EntityBase.class);

    EntityDao entityDao = Mockito.mock(EntityDao.class);
    when(entityDao.getEntityById(paramEntityId, paramEntityType)).thenReturn(entityBase);

    UserDao userDao = Mockito.mock(UserDao.class);
    Organisme organisme = Mockito.mock(Organisme.class);
    Exercice excercice = Mockito.mock(Exercice.class);

    when(userDao.getOrganismeFromSession()).thenReturn(organisme);
    when(organisme.getExercice()).thenReturn(excercice);
    when(userDao.getOrganismeFromSession().getExercice().getDateProjet()).thenReturn(new GregorianCalendar(2000, 01, 01).getTime());

现在,我想测试使用虚假参数paramEntityIdparamEntityTypegetChildren是否能够正确返回WrapperProject 1和01/01/2000,使用模拟的方法,但是我无法找出如何启动read方法,让它使用模拟的dao。

1个回答

4

您的代码不够测试友好,特别是这两行对于测试来说非常糟糕:

EntityDao entityDao = new EntityDao();
UserDao userDao = new UserDao();

这段代码应该从当前方法移动到工厂类或使用容器(如Spring(依赖注入))进行注入。

Mockito无法单独测试此类代码。您的方法应该只做一件事,创建Dao是其他工作。

我会向您推荐两部来自GoogleTechTalks的电影:


谢谢,你说得对,我会关注它们并在这里发布我的最终工作答案。 - maxday
2
我完全同意MariuszS的观点。在我的Mockito wiki文章中,我提到了一些使用Mockito来帮助测试创建新对象代码的方法。快速浏览一下,看看它们是否有用。 - Dawood ibn Kareem
@MariuszS 嗯,对于那个问题的大多数答案都是“不”。当然,实际情况是,单元测试的易用性与是否使用 DI 没有任何关系,而完全取决于能否将被测试的单元与其外部依赖项隔离。例如,PowerMockito 是一种模拟/隔离工具,无论是否使用 DI 都可以很好地完成工作。通常,当人们谈论这些所谓的可测试性问题时,他们似乎没有意识到适当的解决方案已经存在。 - Rogério
@Rogério,我的意思是,考虑到DI编写的代码很容易在没有PowerMockito等工具的情况下进行测试 :) DI有助于编写可测试的代码。此外,David第二个模式是关于注入的 :) - MariuszS
@MariuszS 我同意,依赖注入可以帮助编写可测试的代码。好的测试工具(包括模拟)也是如此。另一方面,以DI为导向的代码也往往呈现出过程式风格,而不是面向对象的;通常会看到无状态服务/DAO“对象”,这些对象被注入和注入到,再加上值“对象”(显然都不是真正的对象)。因此,DI也“帮助”编写糟糕的代码(我已经在使用Spring、CDI或.NET的项目中看到了很多)。另一个问题是,带有任意限制的模拟工具也会阻碍良好的OO代码。 - Rogério
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接