【问题标题】:Unit testing a method with easymock使用 easymock 对方法进行单元测试
【发布时间】:2012-07-18 23:33:22
【问题描述】:

所以我有下面的方法,我想对其进行单元测试。

public List<Project> getProjects(Task task) {

    Criteria<Project> criteria = this.myRepository.getCriteria(Project.class);
    criteria.add(Comparison.eq("order", task.getOrder()));
    criteria.addOrder(Order.asc("projectNumber"));
    return this.myRepository.findList(Project.class, criteria);
}

所以它实际上得到了任务对象(它是一个JPA模型对象)并抛出项目表并找到所有具有该项目订单的项目。两个表中的顺序都很常见。

无论如何,查询本身并不是那个小鬼。它查询数据库并返回一些数据。现在我的问题是如何使用 easymock 对此进行单元测试?

@Test
public void testGetProjects() throws Exception {
    myRepository = new CreateMyRepositoryWrapper(); --> This is a class which just returns the entityManger. but here we can consider this as a pojo.

    Task task = EasyMock.createNiceMock(Task.class);
    Order bom = EasyMock.createNiceMock(Order.class);        
    Project project= EasyMock.createNiceMock(Project.class);

    project.setProjectName("project"); ------> Can I call a seeter on a mocked object?

    project.setProjectNumber("1");

    EasyMock.replay(project);

    List projects= new ArrayList(Arrays.asList(project));
    bom.setProjects(projects);  ------------> Does it make sense to do this?

    EasyMock.expect(task.getOrders()).andReturn(bom);
    TestClass instance = new TestClass();
    instance.setMyRepository(myRepository);

    EasyMock.replay(task,bom);
   instance.getProjects(task);

}

所以这通过了测试用例。但是我不确定所有那些嘲笑我实际测试的东西。因为它只是表明正在调用这些方法。但是由于他们被嘲笑,我不确定我是否可以使用 assertEquals ,即使我可以得到一个异常,因为我认为我必须在上面的代码中添加更多内容。

所以我的问题是:对于提到的方法,正确的单元测试用例应该是什么?

谢谢。

【问题讨论】:

    标签: java unit-testing junit easymock


    【解决方案1】:

    我认为你有这种倒退的嘲讽。模拟 myRepostory,然后设置 myRepository 模拟以返回 Criteria 对象并在 Criteria 对象传递给 findList 时返回项目列表。

    Task、Order 和 Project 可能只是实例化。

    现在,instance.getProjects(task) 将返回一些东西。您可以检查以确保返回的内容与您所说的应该从 findList 返回的内容相同。现在您实际上已经测试了一些东西,尽管没有什么特别有趣的。

    您可能希望在将标准对象传递给 findList 之前验证它是否已正确设置。为此,您要么必须模拟标准,然后您可以设置您对调用哪些方法的期望。这里棘手的部分是 Hibernate Restriction 类没有非默认的 equals 实现,因此您必须编写自己的匹配器来检查传递给条件的限制是否与您期望的限制相同(功能上)。

    另一种可能性是将标准设置为实际的 Criteria 对象。 (您仍然设置 myRepository 模拟以返回它。)然后,在调用该函数后,您可以使用 toString() 方法上的某些子字符串匹配或您知道检查 Criteria 对象的任何其他方式检查内容。

    最后一种(单元测试)的可能性是不使用 Criteria 对象的模拟框架,而是使用您编写的一些手动编码的框架,允许您检查添加到其中的所有限制。

    所有这些都为这个方法提供了一个很好的例子,它实际上是用集成测试来测试的。您最终会做大量工作来验证一些不太有趣的事情,如果您尝试重构代码,您的测试可能会变得非常脆弱。 (我自己做过,所以我根据经验说话。)

    【讨论】:

    • 非常感谢您的宝贵时间。但我不明白的是,如果我模拟存储库对象并告诉它在 findList 调用时返回这些项目。然后它会返回我告诉它的内容。那么当我告诉它返回我想要的东西时,我应该将它与什么进行比较,这样无论标准是否有效,它都会返回我想要的东西。唯一的事情是我可以启动项目,然后检查标准是否正确。但是我也可以检查它是否也使用模拟存储库返回正确的东西吗?
    • 我在这里模拟的问题是,一般来说,如果我模拟存储库并告诉它我期望的返回类型,那么我如何测试它是否返回正确的数据?我错过了什么吗?
    • 单元测试的重点(与集成测试相反)是您不想测试CreateMyRepositoryWrapper。您假设该类将正常工作(您希望基于其他测试)。在嘲笑中,你说,“假设 myRepository 这样做 - 这个方法是否像我预期的那样工作?”通过这种方式,您可以轻松测试其他场景,例如myRepository.findList 返回 null - 我要从该方法返回 null 还是空列表?假设myRepository.findList 抛出一个异常——我是想处理那个异常还是让它级联?
    • 我希望我能不止一次喜欢你的评论 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 2021-09-16
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多