【问题标题】:Set System Properties for JUnit Test before ServletContextListener uses file path from web.xml在 ServletContextListener 使用来自 web.xml 的文件路径之前为 JUnit 测试设置系统属性
【发布时间】:2016-10-04 16:16:58
【问题描述】:

我正在修改使用 Spring 3.1.4 的旧项目。

我正在尝试使用 StartupListener 来配置 Logback:

public class LoggingStartupListener implements ServletContextListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingStartupListener.class.getName());


@Override
public void contextInitialized(final ServletContextEvent sce) {
    final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
    context.reset();
    final JoranConfigurator configurator = new JoranConfigurator();
    final ServletContext servletContext = sce.getServletContext();
    final StringBuilder filePath = new StringBuilder(100);
    filePath.append(servletContext.getRealPath("/"));
    filePath.append(servletContext.getInitParameter("logFileName"));
    InputStream configStream = null;
    try {
        configStream = FileUtils.openInputStream(new File(filePath.toString()));

...

它正在从 web.xml 读取文件路径:

<context-param>
    <param-name>logFileName</param-name>
    <param-value>/WEB-INF/config/${spring.profiles.active}/logback.xml</param-value>
</context-param>

现在,当我运行 JUnit 测试时,我总是遇到异常:

java.io.FileNotFoundException: File '/var/folders/v7/1r3m8y8j487dqj7vmvb4n4kxcw70fj/T/tomcat-embedded-77438108580291256392.tmp/webapps/myproject/WEB-INF/config/${spring.profiles.active}/logback.xml' does not exist
at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:136)

这意味着 spring.profiles.active 属性永远不会被解析。

我尝试了各种方法:

1)我尝试在测试前设置属性:

@BeforeClass
public static void setSystemProperty() {
    System.out.println("---------------------BeforeClass--------------------");
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().setActiveProfiles("local");
    ctx.refresh();

    System.setProperty("spring.profiles.active", "local");
}

但它不起作用,因为这个方法是在抛出错误之后调用的。 (“---------BeforeClass-------------”出现在日志中的错误之后。)

2)我尝试在测试类之前使用注解:

@ActiveProfiles(profiles = "local")

3) 我尝试使用 spring-test.properties 文件设置属性:

spring.profile.active=local

并将其包含在测试上下文中:

<context:property-placeholder location="classpath:spring-test.properties"/>

-> 没有任何影响

4) 我什至尝试直接在 ServletContextListener 中设置属性:

@Override
public void contextInitialized(final ServletContextEvent sce) {
    System.setProperty("spring.profiles.active", "local");
    ...

这真的让我感到惊讶,因为这应该有效,不是吗?

是否因为我使用的是旧的 Spring 版本而遇到这些问题?在其他具有更高 Spring 版本的项目中,我从未遇到过这些问题。 或者我错过了什么?

我可以将侦听器配置为稍后启动吗?或者我可以在 ServletContextListener 启动之前配置单元测试来设置系统属性吗?

或者以不同的方式初始化 logback 以避免这些问题会更好——但是为什么它们不出现在其他项目中呢?

我找到了这个,但我不知道这是否适用于我的案例: Spring-test and ServletContextListener in web.xml

它说没有办法使用 Spring MVC 测试配置 ServletContextListener。它说我可以尝试用

覆盖上下文参数
wac.getServletContext().setInitParameter(name, value);

但我不知道什么时候/在哪里做,因为 web.xml 显然是在初始化测试类之前读取的。

非常感谢任何提示

【问题讨论】:

  • 似乎ServletContextListenerSpring 生命周期之前执行,因此spring.profiles.active 没有自动解决Spring 的预期。也许您应该尝试从您的 contextInitialized 方法中手动获取该密钥。

标签: java spring junit servletcontextlistener spring-profiles


【解决方案1】:

我使用 logback spring 扩展而不是我们自己的实现,这样问题就消失了!

我使用了这个文档: https://github.com/qos-ch/logback-extensions/wiki/Spring

其中一个特点是: - “使用 Spring 资源路径和系统属性占位符指定 logback.xml 位置。”

正是我需要的。我使用的是 0.1.4 版本的 logback-ext-spring。

【讨论】:

    猜你喜欢
    • 2017-04-17
    • 2012-06-15
    • 1970-01-01
    • 2017-08-12
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多