繁体   English   中英

我怎样才能在java中对这个方法进行单元测试?

[英]How can I unit test this method in java?

我正在使用Struts2框架,并希望对下面的execute方法进行单元测试:

public String execute() {
    setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));
    setUserPrincipal(); //fetches attribute from request and stores it in a var
    setGroupValue(); //
    setResults(getMyDao().getReportResults(getActionValue(), getTabName());
    setFirstResultSet((List) getResults()[0]);
    setSecondResultSet((List) getResults()[1]);
    return SUCCESS;
}

正如您所看到的,大多数逻辑都与数据库相关。 那么我该如何进行单元测试呢? 我想通过模拟HTTPServletRequest来进行单元测试,其中包含很少的请求变量。

我的问题是:

  • 如何伪造/模拟请求变量,就好像它来自浏览器一样
  • 我的单元测试应该调用实际的DAO并确保数据回来吗?
  • 如果是这样,我怎么能从单元测试中调用DAO,因为DAO绑定到服务器,因为jndi池设置驻留在应用程序服务器上。

我很欣赏任何展示如何真正实现这一目标的书/文章。

您向我们展示的代码不足以完全回答您的问题。

逐行

setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));

这是最难的一行,因为它使用静态方法。 我们需要看看ApplicationInitializer工作原理。 理想情况下, getApplicationContext()方法应该返回ApplicationContext mock。 这个模拟轮流应该在getBean("MyDAO")时返回MyDAO 完全有能力处理这个,以及所有其他模拟框架。


setUserPrincipal(); //fetches attribute from request and stores it in a var

请求来自哪里? 是否注入了动作类? 如果是这样,只需注入模拟的请求对象,例如MockHttpServletRequest


setGroupValue(); //

和上面一样? 请提供更多详细信息,这种方法实际上做了什么?


setResults(getMyDao().getReportResults(getActionValue(), getTabName());

当使用给定参数调用getReportResults()时,您之前创建的模拟应返回一些内容。


setFirstResultSet((List) getResults()[0]);
setSecondResultSet((List) getResults()[1]);

我想下面的方法在action类上设置了一些字段。 因为您可以完全控制从getReportResults()返回的内容,所以这不是问题。


return SUCCESS;

您可以断言SUCCESS是否是执行的结果。


现在一般

如何伪造/模拟请求变量,就好像它来自浏览器一样

如上所述,Spring中有一个内置的模拟器。

我的单元测试应该调用实际的DAO并确保数据回来吗?

如果您的单元测试称为真正的DAO,则它不再是单元测试。 这是一个集成测试。

如果是这样,我怎么能从单元测试中调用DAO,因为DAO绑定到服务器,因为jndi池设置驻留在应用程序服务器上。

这意味着您正在进行集成测试。 在这种情况下,您应该使用像这样的内存数据库,这样您仍然可以在服务器上运行测试。 您必须以某种方式配置您的应用程序以从不同的地方获取DataSource


最后的说明

从本质上讲,你应该向Struts动作类注入所有内容的模拟。 你可以告诉mocks在调用时返回任何值。 然后,在调用execute() ,您可以验证调用给定的方法,字段集和结果值是否正确。 考虑将其拆分为多个测试。


代码审查

  • Struts 2与Spring完美集成。 如果您利用该功能,Spring容器会自动将MyDAO注入您的操作类。 第一行变得过时了。

此代码很难进行单元测试,因为您不是按预期使用Spring(即作为依赖注入框架),而是将其用作工厂。 依赖注入正好用于避免您正在进行的这种bean查找,这很难测试。 应将DAO注入您的对象。 这样,您可以在单元测试对象时注入模拟DAO。

此外,该逻辑根本不与数据库相关。 DAO包含与数据库相关的逻辑。 此操作使用 DAO,因此DAO是另一个单元(应在其自己的单元测试中进行测试)。 因此,您应该注入一个模拟DAO来对此方法进行单元测试。

最后,这个方法不使用HttpServletRequest(至少不是直接),所以我不明白为什么你需要使用假的请求。 您可以模拟使用该请求的setXxx方法。

  1. 而不是简单地模拟HTTPServletRequest ,如何模拟实际的自动目标请求到应用程序本身? 查看Selenium ,它可以让你做到这一点。

  2. 对于测试DAO(集成测试),您可以使用HSQLDB在内存中创建数据库,这将允许您从测试中创建/删除对象,并确保它们被正确保留/检索。 HSQLDB的优势在于您的测试运行速度比实际数据库快得多。 在提交代码时,您可以针对实际数据库运行测试。 通常,您可以在IDE中设置不同的运行配置以实现此目的。

  3. 使注入的daos可用于测试的最简单方法是让您的单元测试类扩展AbstractJUnit4SpringContextTests 然后,您可以使用@ContextConfiguration批注指向多个xml应用程序上下文文件,或者如果使用基于注释的配置,则将其指向您的上下文文件,其中包含<context:annotation-config />声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM