如何为SpringJUnit4ClassRunner配置log4j.properties?

67

在进行 JUnit 测试时,突然出现了这种情况。之前一切正常,我写了一些新的测试,然后出现了这个错误。如果我回滚代码,问题仍然存在。为什么会这样呢?

log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
7个回答

73
您写的新测试(直接或间接)使用了使用Log4j记录日志的类。
需要正确配置Log4J才能使记录日志正常工作。
在测试类路径的根目录下放置一个log4j.properties(或log4j.xml)文件。
它应该具有一些基本配置,例如:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

# An alternative logging format:
# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

默认情况下,一个 appender 会输出到控制台,但是你也可以明确地设置目标,如下所示:
log4j.appender.A1.Target=System.out

这将以良好的格式将所有输出重定向到控制台。更多信息可以在Log4J手册中找到。

然后,Log4J日志记录将被正确配置,并且此警告将消失。


1
仅供参考,这里是转换模式参考链接:http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/EnhancedPatternLayout.html - lanoxx
1
你能解释一下我们为什么要这样做吗? - iLoveCamelCase
1
project/src/test/resources/log4j.properties - Josue Abarca
有人能用 XML 语法解释一下这个吗? - C.J.

50

如果您不想使用文件来麻烦自己,可以在代码中尝试如下操作:

static
{
    Logger rootLogger = Logger.getRootLogger();
    rootLogger.setLevel(Level.INFO);
    rootLogger.addAppender(new ConsoleAppender(
               new PatternLayout("%-6r [%p] %c - %m%n")));
}

1
救了一天!感谢 @tster。 - Kevin Rave
为什么我没想到那个?谢谢! - Kronen

8
在您的类路径根目录下添加一个log4j.properties(或log4j.xml)文件,其中至少有一个appender。
该文件(log4j.properties)的内容可以非常简单,例如:
log4j.rootLogger=WARN,A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c %x - %m%n

这会启用默认日志级别为WARN的log4j日志记录,并使用Java控制台记录消息。


4
我已经正确配置了log4j.properties。问题不在这里。过了一段时间后,我发现问题出在Eclipse IDE上,它有一个旧版本的“缓存”,没有创建新的版本(Maven依赖问题)。我不得不手动构建项目,现在它可以工作了。

嗨Tom,你能详细说明一下这个问题和解决方法吗?我也觉得我遇到了同样的问题!谢谢。 - VLostBoy
@vlostboy: 对我有效的解决方案是从命令行进行构建:mvn clean package - user219882
1
感谢您回复我Tom- 我认为我解决了这个问题- 是我的错,我在资源中有log4j.properties和log4j.xml两个文件。我删除了properties文件,简化了xml配置,现在一切似乎都正常工作了,但如果我再次遇到这个问题,我肯定会尝试使用maven clean。 - VLostBoy
哎呀,我已经抓狂了几个小时了,相信这就是答案。 - dwjohnston

3
我曾在eclipse中使用Maven,但我不想在根文件夹中再添加一份属性文件的副本。您可以按照以下步骤操作:
  1. 打开运行对话框(单击播放按钮旁边的小箭头并转到运行配置)
  2. 转到“类路径”选项卡
  3. 选择“用户条目”,然后单击右侧的“高级”按钮。
  4. 现在选择“添加外部文件夹”单选按钮。
  5. 选择资源文件夹

2

因为我不喜欢有重复的文件(例如test和main中的log4j.properties),而且我有相当多的测试类,它们都是使用SpringJUnit4ClassRunner类运行的,因此我必须对其进行自定义。这是我使用的:

import java.io.FileNotFoundException;

import org.junit.runners.model.InitializationError;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Log4jConfigurer;

public class MySpringJUnit4ClassRunner extends SpringJUnit4ClassRunner {

    static {
        String log4jLocation = "classpath:log4j-oops.properties";
        try {
            Log4jConfigurer.initLogging(log4jLocation);
        } catch (FileNotFoundException ex) {
            System.err.println("Cannot Initialize log4j at location: " + log4jLocation);
        }
    }

    public MySpringJUnit4ClassRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }
}

当您使用它时,请将SpringJUnit4ClassRunner替换为MySpringJUnit4ClassRunner。
@RunWith(MySpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:conf/applicationContext.xml") 
public class TestOrderController {
    private Logger LOG = LoggerFactory.getLogger(this.getClass());

    private MockMvc mockMvc;
...
}

2

我知道这已经过时了,但是我也遇到了问题。对于使用Maven和Eclipse的Spring 3,我需要将log4j.xml放在src/test/resources中,以便单元测试能够正确记录日志。将其放在测试根目录中对我来说无效。希望这能帮助其他人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接