【问题标题】:Classpath order differs depending on JUnit runner类路径顺序因 JUnit 运行器而异
【发布时间】:2014-04-10 12:27:39
【问题描述】:

我面临的问题与this question 中暴露的问题相似,但我认为不同,希望更容易解决。

我有一个单元测试类TestMyClass 来测试MyClass,而MyClass 恰好有一个对log4j 记录器的静态引用。

当我用@RunWith(MockitoJUnitRunner.class) 运行TestMyClass 时,记录器的初始化很顺利。但是当我使用@RunWith(PowerMockRunner.class) 运行测试时,log4j 在初始化记录器时会记录以下错误:

log4j:错误“org.apache.log4j.xml.DOMConfigurator”对象不可分配给“org.apache.log4j.spi.Configurator”变量。
log4j:ERROR 类“org.apache.log4j.spi.Configurator”由
加载 log4j:ERROR [org.powermock.core.classloader.MockClassLoader@1ad186f] 而对象类型
log4j:错误“org.apache.log4j.xml.DOMConfigurator”由 [sun.misc.Launcher$AppClassLoader@13f5d07] 加载。
log4j:ERROR 无法实例化配置器 [org.apache.log4j.xml.DOMConfigurator]。

我发现这是因为下面的sn-p在log4j初始化代码中返回false

Configurator.class.isAssignableFrom(DOMConfigurator.class)

这应该是真的,DomConfigurator 实现了Configurator,但我认为它返回错误,因为我在类路径上碰巧有这些类的两个版本:一个来自 log4j-1.2.14,一个来自 log4j-extras- 1.1。而且我想当使用PowerMockRunner 运行测试时,这两个类不是从同一个jar 加载的(如果可能有其他原因,请告诉我)。

所以我想了解:

  • 为什么我会遇到这个问题?为什么类路径顺序会因使用的 JUnit 运行器而异?它不应该是确定性的吗?
  • 有没有办法解决这个问题?

注意:我必须使用PowerMockRunner,因为我需要模拟一个静态调用。我无法摆脱其中一个 log4j jar,因为它们都是我项目依赖项的依赖项。这个问题不会让我的测试失败,它只是打印那些错误,但如果能解决它还是不错的。

【问题讨论】:

    标签: java maven junit classpath


    【解决方案1】:

    我不再记得为什么我们必须这样做,但是我们使用 PowerMock 模拟静态方法的测试类之一在顶部有这个,就在 @PrepareForTest 注释下方:

    @PowerMockIgnore({ "org.apache.log4j.*", "org.apache.commons.logging.*" })
    

    PowerMock FAQ 中的第 5 项给出了可能需要这样做的几个原因,并提出了其他解决方案。忽略 log4j 对我们有用。

    附:我们正在使用 PowerMock 1.5.1。

    【讨论】:

    • 我不知道我是怎么错过了常见问题解答的这一部分,但它对我也很有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2012-01-18
    • 2014-01-29
    相关资源
    最近更新 更多