当前位置: 首页 > 知识库问答 >
问题:

Easymock:正在执行模拟

苍意智
2023-03-14

因此,这是我第一次使用EasyMock,我正在尝试向一些遗留代码添加一些单元测试。

遗留代码在Spring 3.1中,我使用的是EasyMock 3.4。

我在这里试图完成的是测试一个调用dao的服务(在Spring中编写的方法)。

代码如下:

@Entity
@Table(name="comment")
public class CommentBO{


    public static CommentBO createNewComment(Integer clientNumber, Integer commentCategory){

    CommentBO bo = new CommentBO();
    bo.setClientNumber(clientNumber);
    bo.setCommentCategory(commentCategory);
    return bo;
    }
}

public interface AssessmentService {
    public CommentBO getComment(Integer clientNumber, Integer 
commentCategory);
}

public class AssessmentServiceImpl implements
    AssessmentService {

    @Resource(name = "com.client.assessment.bl.dao.AssessmentDao")
    private AssessmentDao assessmentDao;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.REQUIRED)
    public CommentBO getComment(Integer clientNumber,Integer commentCategory) {

    CommentBO comment = this.assessmentDao.getComment(
            clientNumber, commentCategory);

    if (comment != null && comment.getComments() != null) {
        comment.setComments(comment.getComments().replaceAll("<li>&bull;",
                "<li>"));
    }

    return comment;
}


public interface AssessmentDao {

    public CommentBO getComment(Integer clientNumber, Integer commentCategory);
}


@Repository(value = "com.client.assessment.bl.dao.AssessmentDao")
public class AssessmentDaoImpl implements AssessmentDao {

    @Override
    public CommentBO getComment(Integer clientNumber, Integer 
commentCategory) {
        Criteria criteria = 
this.getSession(false).createCriteria(CommentBO.class);
        criteria.add(Restrictions.eq("clientNumber", clientNumber))
            .add(Restrictions.eq("commentCategory", commentCategory));

        if (criteria.list() != null && criteria.list().size() > 0) {
           return (CommentBO) criteria.list().get(0);
       }

       return null;
    }
}

这是我用EasyMock编写的单元测试

@SpringApplicationContext("classpath*:/com/client/assessment/**/*-context.xml")
public class AssessmentServiceTest extends UnitilsJUnit4   {

    @SpringBean("com.client.assessment.remote.AssessmentService")
    public AssessmentService assessmentService = null;

    @Test
    public void testGetComment(){

    Integer clientNumber = 1;
    Integer commentCategory = 1;
    CommentBO commentBO = CommentBO.createNewComment(clientNumber, commentCategory);

    AssessmentDao assessmentDao = EasyMock.createMock(AssessmentDao.class);

    EasyMock.expect(assessmentDao.getComment((Integer) anyObject(), (Integer) anyObject())).andReturn(commentBO).anyTimes();

    ReflectionTestUtils.setField(assessmentService, "assessmentDao", assessmentDao);

    EasyMock.replay(assessmentDao);

    CommentBO bo = assessmentService.getComment(clientNumber, commentCategory);

    assertThat( bo , instanceOf(CommentBO.class));
    }

}

所以基本上发生的是,我的单元测试失败了,因为

assessmentService.getComment(clientNumber, commentCategory);

为空!

是的,如果它实际被执行,它将为空,因为在数据库中没有clientNumber=1和评论类别=1的记录。

这就是为什么,我想嘲笑所说的dao并强制它返回CommentBO对象。

正如我上面所说,这是我第一次使用EasyMock,所以我是否遗漏了一些明显的东西?我是否需要在dao方法内模拟调用(即评估dao的getComment)?但如果我这样做,我会被迫嘲笑Criteria对象等,我认为这是不好的做法?

共有1个答案

邢俊悟
2023-03-14

当前代码应该可以工作。因此,我看到的唯一可能性是,getComment实际上是最终的。如果您随时删除并在断言之前添加一个验证,您应该会看到缺少调用。

唯一的另一种可能性是反射TestUtils无声失败。所以你仍然有原始的Spring bean注入。如果你调试,你会很容易看到服务中注入的DAO不是模拟的。

我已经重写了下面的代码。它工作得很好。

public interface AssessmentDao {
  CommentBO getComment(Integer clientNumber, Integer commentCategory);
}

public class AssessmentDaoImpl implements AssessmentDao {
  @Override
  public CommentBO getComment(Integer clientNumber, Integer commentCategory) {
    throw new AssertionError("Should not be called");
  }
}

public interface AssessmentService {
  CommentBO getComment(Integer clientNumber, Integer commentCategory);
}

public class AssessmentServiceImpl implements AssessmentService {

  private AssessmentDao assessmentDao;

  @Override
  public CommentBO getComment(Integer clientNumber, Integer commentCategory) {
    CommentBO comment = this.assessmentDao.getComment(clientNumber, commentCategory);

    if (comment != null && comment.getComments() != null) {
      comment.setComments(comment.getComments().replaceAll("<li>&bull;", "<li>"));
    }

    return comment;
  }
}

public class CommentBO {

  public static CommentBO createNewComment(Integer clientNumber, Integer commentCategory) {
    CommentBO bo = new CommentBO();
    bo.setClientNumber(clientNumber);
    bo.setCommentCategory(commentCategory);
    return bo;
  }

  private Integer clientNumber;
  private Integer commentCategory;
  private String comments;

  public Integer getClientNumber() {
    return clientNumber;
  }

  public void setClientNumber(Integer clientNumber) {
    this.clientNumber = clientNumber;
  }

  public Integer getCommentCategory() {
    return commentCategory;
  }

  public void setCommentCategory(Integer commentCategory) {
    this.commentCategory = commentCategory;
  }

  public String getComments() {
    return comments;
  }

  public void setComments(String comments) {
    this.comments = comments;
  }
}

public class ReflectionTestUtils {

  public static void setField(Object object, String fieldName, Object value) {
    try {
      Field field = object.getClass().getDeclaredField(fieldName);
      field.setAccessible(true);
      field.set(object, value);
    }
    catch(Exception e) {
      throw new RuntimeException(e);
    }
  }
}

public class AssessmentServiceTest   {

  public AssessmentService assessmentService = new AssessmentServiceImpl();

  @Test
  public void testGetComment(){

    Integer clientNumber = 1;
    Integer commentCategory = 1;
    CommentBO commentBO = CommentBO.createNewComment(clientNumber, commentCategory);

    AssessmentDao assessmentDao = EasyMock.createMock(AssessmentDao.class);

    expect(assessmentDao.getComment(anyObject(), anyObject())).andReturn(commentBO);

    ReflectionTestUtils.setField(assessmentService, "assessmentDao", assessmentDao);

    replay(assessmentDao);

    CommentBO bo = assessmentService.getComment(clientNumber, commentCategory);

    verify(assessmentDao);

    assertThat(bo , instanceOf(CommentBO.class));
  }

}

 类似资料:
  • 我有几个类遵循“模板方法”模式。抽象类A,具体扩展类B和C,如下所示: 我想编写一个测试来验证当getData()抛出某个Exception时是否抛出其他Exception。我真的希望避免模拟强制getData()抛出所需的所有复杂依赖关系。我不关心getData()如何抛出,我只想让它抛出。所以我想我要的是部分模拟。这就是我所拥有的: 这个测试在我看来很好,但当我运行它时,我得到了这样的结果:

  • 我尝试从以下方法创建单元测试,但我找不到一个解决方案来模拟每个方法内的调用,请您帮助我使用EasyMock为这些方法创建JUnit Test: 提前感谢

  • 模拟由某个类实现的接口方法很容易,但如果有一个类并且有一个静态方法,那么我们如何借助easymock对其进行模拟呢?? supose是一个a类,有一个void retruned方法作为公共静态void methodA(一些参数…){} 我们如何在EasyMock的帮助下模仿A的方法methodA

  • 我正在尝试创建一个应用程序,用于查询cat图像的站点,如果JSON ID是唯一的,则将其保存到android设备,然后从设备以幻灯片格式显示它们。尽管如此,我的AsyncTask似乎并没有实际执行。调试器确认已建立网络连接,并且不会向我反馈任何错误,所以我不知道代码出了什么问题。希望有人能帮忙!代码如下:

  • 我正在尝试为以下类编写单元测试: 还有一些其他方法,但这个设置代码是与我的问题相关的。在单元测试中,我想模拟(使用EasyMock)对象以及它将返回的和对象: 当我尝试用JUnit运行它时,我得到以下错误: 在上没有我可以看到的公共变量。我是EasyMock的新手,所以我想我的问题是:对于我应该告诉我的mock返回什么,以及如何告诉它这样做?我根本不知道为什么设置代码会被调用,所以这是另一个谜。更

  • No alarms and no surprises. — Radiohead 我讨厌惊喜。有时你的 Puppet 配置清单没有像你预期的那样执行, 或者在你不知情的情况下,或许别人又提交了改变。 不管哪种情况发生,在 Puppet 执行配置清单之前能精确地获知它将要执行些什么是非常必要的。 例如,若更新了一个生产服务的配置文件并重新启动该服务,很可能会导致非计划性的停机时间。 又如,有时人为的手