Easymock:mock 正在执行

Easymock: mock is being executed

所以这是我第一次使用 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 和 commentCategory = 1 的记录。

这就是为什么,我想嘲笑所说的 dao 并将其强制为 return CommentBO 对象。

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

当前代码应该可以工作。所以我看到的唯一可能性是 getComment 实际上是最终的。如果删除 anyTimes 并在断言前添加 verify,您应该会看到缺少调用。

唯一的另一种可能性是 ReflectionTestUtils 默默地失败了。所以您仍然注入了原始的 spring bean。如果你调试,你会很容易地看到服务中注入的 DAO 不是 mock。

我已经在下方重写了您的代码。效果很好。

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));
  }

}