java - Powermock - 模拟 org.apache.log4j.Logger?我怎么能够?

标签 java unit-testing mockito powermock

我想知道用 powermock(和 mockito)模拟 org.apache.log4j 的最简单和最简洁的方法是什么。

我已经尝试了几种方法(我不会在这里说明)但还没有找到实现我想要的方法。我创建了一个简单的类来在下面进行测试,我想调用 run 方法并验证是否已调用 log.info 消息。我该怎么做呢?如果您知道怎么做,我敢肯定这会很容易!

(我正在使用@Rule,因为我想在 Spring 测试下运行,但这应该没有什么区别)。

非常感谢您提供正确的代码。

import org.apache.log4j.Logger;
import org.junit.Rule;
import org.junit.Test;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;

public class MockLog4JTest
{
    @Rule
    public PowerMockRule rule = new PowerMockRule();

    private static class ClassUnderTest
    {
        private static Logger logger = Logger.getLogger(ClassUnderTest.class);

        public void run() {
            logger.info("Hello.");
        }

    }

    @Test
    public void testLog()
    {
        ClassUnderTest classUnderTest = new ClassUnderTest();
        classUnderTest.run();
    }

}

最佳答案

Chris 和 Fildor 尝试模拟 Logger.getLogger() 是正确的。不幸的是,Log4J 的工作方式让这在技术上变得棘手。

这是我根据您上面的示例提出(测试)的代码。

ClassUnderTest.java

import org.apache.log4j.Logger;

public class ClassUnderTest {
    private static Logger logger = Logger.getLogger(ClassUnderTest.class);

    public void run() {
        logger.info("Hello.");
    }
}

MockLog4JTest.java

import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mock;

import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.powermock.reflect.Whitebox;

@PrepareForTest(ClassUnderTest.class)
public class MockLog4JTest {
    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @BeforeClass
    public static void oneTimeSetup() {
        System.setProperty("log4j.defaultInitOverride", Boolean.toString(true));
        System.setProperty("log4j.ignoreTCL", Boolean.toString(true));
    }

    @Test
    public void testLog()
    {
        ClassUnderTest classUnderTest = new ClassUnderTest();
        Logger mockLogger = mock(Logger.class);

        Whitebox.setInternalState(ClassUnderTest.class, "logger", mockLogger);

        classUnderTest.run();

        verify(mockLogger).info(eq("Hello."));
    }
}

我选择使用 Whitebox 将被测类的静态字段直接设置为我的 mockLogger 实例。之后,验证就非常简单了。

关于java - Powermock - 模拟 org.apache.log4j.Logger?我怎么能够?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19006087/

相关文章:

java - 能否通过Guava库提供的Maps.filteKey/Value方法实现类似数据库的Limit功能

mocking - 自定义匹配器的 Mockito 错误

java - Mockito 对象为 null

java - JMockit:当应该实例化模拟对象时出现空指针错误?

testing - 如何 Junit 测试具有特定响应的 servlet 过滤器

java - 为什么 OpenCV 的 MSER 的 Python 实现和 Java 实现会产生不同的输出?

java - 为什么 Maven 存储库中的库无法编译?

java - WindowBuilder 相当于 IntelliJ?

c# - 为 EF dbcontext 设置模拟对象以测试存储库方法

javascript - 如何在 Jest 中进行单元测试并检查函数是否正在调用预期的 firebase 方法?