【问题标题】:Spring Unit/Intergration Testing setup弹簧单元/集成测试设置
【发布时间】:2010-02-12 22:09:41
【问题描述】:

我没有编写单元测试或集成测试,但现在我正在尝试。我很难设置环境。

我在 WEB-INF/applicationContext*.xml 下有我的应用程序上下文 在我的 applicationContext.xml 中,它引用了 DB 用户/密码、LDAP 主机等的属性文件

<bean id="propertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>/WEB-INF/spring-config/dev.properties</value>
            </list>
        </property>
    </bean>

我有另一个 log4j 配置属性(DEV/Staging/Production 的差异配置)。 ${webapp.root} 在 web.xml 中定义

 <!-- log4j setting -->
    <bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
        <property name="targetMethod" value="initLogging" />
        <property name="arguments">
            <list>
                <value>${webapp.root}/${log4j.properties.location}</value>
            </list>
        </property>
    </bean>

现在我正在尝试将以下内容放入测试类中。

@Override
protected String[] getConfigLocations() {
   return new String[]{
            "file:trunk/code/web/WEB-INF/applicationContext.xml",
        };
}

这正确引用了我的 xml,但所有属性都搞砸了。

我想知道以下内容:

  • 有没有办法在测试类中正确设置?如果没有,我应该移动这些课程吗?
  • 如果存在对仅存在于容器中的 webroot 的引用,我该如何设置 Log4j?!
  • Spring 配置位置的最佳做法是什么?

请指教

谢谢

【问题讨论】:

  • 你成功了吗?分享吧。

标签: java spring junit log4j


【解决方案1】:

This blogpost of mine 描述了实现目标的基本步骤。

请注意,单元测试不应该知道您有一个 webapp-root - 它们通常在没有任何 servlet 容器启动的情况下运行。因此,将替代配置文件放在测试包中并尝试。

【讨论】:

  • 这正是我最终要做的。每个模块都有单元测试和一个自定义的 test-application-context.xml 文件,单元测试通过 Spring 的 @ContextConfiguration 注释引用该文件。能够为我们项目中的每个 Maven 模块设置一个包含任何模拟测试装置的上下文真是太棒了。对于集成测试,每个模块都有一个不同的integrationtest-application-context.xml,它会从所有依赖模块中引入 bean。
【解决方案2】:

对于单元测试,您不应该使用 Spring 应用程序上下文。您应该单独测试所有 Spring bean 和控制器,因为它们是系统中的各个单元。由于它们是 POJO,因此很容易在测试用例代码中以编程方式将所有内容连接在一起。这还解决了诸如日志记录属性文件的位置等问题,因为您可以通过编程方式指定不依赖于 webroot 属性的不同路径。

Spring 参考中的testing chapter 很好地概述了如何对使用 Spring 的应用程序进行单元和集成测试。它还提供了 Spring 提供的各种支持类的详细信息,以帮助编写单元和集成测试。

【讨论】:

  • 如果您没有用于单元测试的应用程序上下文,那么您就不能使用 spring 将各种 bean 注入到您的测试夹具中。那么你不会错过测试的一个重要方面吗?还是应该两者都做?
  • 我会说不使用应用程序上下文的测试是单元测试,因为您只测试单个单元,因此以编程方式注入 bean 并不重要。如果您使用应用程序上下文,我会说这更像是一个集成测试,因为您正在明确测试所有内容如何组合在一起。
  • @HDave 我会说你应该两者都做。同意 Mark 关于单元测试和集成测试的区别。如果您需要在上下文中运行,那么您就不会尽可能地获得单元测试提供的反馈速度。最重要的是,您绝对不是在做 TDD。不是你必须这样做。只是说...
  • 我同意你应该两者都做,但我不同意仅仅存在应用程序上下文就意味着它是集成测试而不是单元测试。也许这是一条很好的路线,但我更愿意将集成测试视为涉及多个软件模块。就我而言,某些单元测试需要某些模拟测试夹具,这些夹具在测试应用程序上下文中设置得更好、更容易。也就是说,90% 的情况下,当人们说他们在单元测试时使用 Spring 应用程序上下文时,他们是在连接来自其他软件模块的 bean……这就是集成测试。
【解决方案3】:

您可以使用注释从测试中引用必要的配置,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
     DependencyInjectionTestExecutionListener.class,
     DirtiesContextTestExecutionListener.class,
     TransactionalTestExecutionListener.class })
@ContextConfiguration(locations = {
     "file:../WebService/src/main/resources/application-context.xml",
     "file:../ServiceLayer/src/test/resources/ServiceLayer-dao-test-context.xml" })
public class MyTest {
     // class body...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    相关资源
    最近更新 更多