当前位置: 代码迷 >> java >> 如何测试使用需要初始化的记录器的旧代码?
  详细解决方案

如何测试使用需要初始化的记录器的旧代码?

热度:106   发布时间:2023-07-16 17:34:38.0

我正在为使用类似于以下记录器的遗留代码编写单元测试

public class MyLogger {
    private static Logger logger;

    public static void init() throws SomeException {
        //initialize the logger field
    }

    public static Logger getLogger() {
        return logger;
    }
}

记录器需要初始化,否则返回null,并且由于使用记录器的被测代码产生NullPointerException导致测试失败

我的目标是测试遗留代码,而在测试时完全不依赖记录器(无论是否初始化)。

可能的解决方案:

  1. 在测试中添加对MyLogger.init()的调用-由于许多原因,这是不好的解决方案。
  2. 如果尚未初始化记录器,请在getLogger进行初始化-我不喜欢这种解决方案,因为这样getLogger必须处理'SomeException'。
  3. 使用不执行任何操作的“ NullLogger”初始化记录器。

我选择了解决方案#3,但这需要我从Logger(具有大约60个函数)继承,并调用其构造函数,并仔细检查从我的代码中调用了logger的哪些方法,因此我可以选择适当的“空”实现。

我的问题有更好的解决方案吗?

使用NullLogger框架创建NullLogger 您可以使用“ Mockito”或“ PowerMock”或“ EasyMock”或任何其他框架。

模拟对象是自动生成的子类,可以通过编程定义其行为。 默认情况下,模拟对象的功能将不执行任何操作并返回null(对于非void方法)。

您可能希望将记录器字段更改为打包隐私,以便能够在测试内部进行设置而不必使用反射。

使用Mockito 1.9.5的示例代码:

import java.util.logging.*;
import org.junit.Test;
import org.mockito.Mockito;

class SomeException extends Exception {

}

class MyLogger
{
    static Logger logger; // changed to package privacy
    public static void init() throws SomeException {
        //initialize the logger field
    }
    public static Logger getLogger() {
        return logger;
    }
}

public class MyLoggerTest {

    @Test
    public void someTest() {

        // set "NullLogger"
        MyLogger.logger = Mockito.mock(Logger.class);

        // access to logger won't fail anymore
        MyLogger.getLogger().log(Level.SEVERE, "uninteresting stuff");
    }
}
  相关解决方案