Java_UT_Mock系列之-06Powermock与Logger

简介

日志几乎是所有应用所必备的模块。 在单元测试中,有时候也需要与日志类打交道。笔者用以下案例来介绍如何mock日志类,并完成相关代码行的覆盖。截图为IDE中覆盖率插件的分析结果。

image

测试代码

具体测试代码如下:

import org.junit.BeforeClass;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.Mockito;

import org.powermock.core.classloader.annotations.PrepareForTest;

import org.powermock.modules.junit4.PowerMockRunner;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import demo.org.powermock.examples.LoggerDemo;

import static org.mockito.Mockito.*;

import static org.powermock.api.mockito.PowerMockito.mock;

import static org.powermock.api.mockito.PowerMockito.*;

import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)

@PrepareForTest({LoggerFactory.class})

public class TestLoggerDemo {

    private static Logger loggerMock;

    @BeforeClass

    public static void setup() {

        mockStatic(LoggerFactory.class);

        loggerMock = mock(Logger.class);

        when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);

    }

    @Test

    public void testLoggerInfo() {

    //when(loggerMock.isDebugEnabled()).thenReturn(true);

    LoggerDemo loggerDemo = new LoggerDemo();

    loggerDemo.toInt("100");

    //notify here is using atLeastOnce() because that loggerMock is static and all the call will be counted.

        verify(loggerMock, atLeastOnce()).info(Mockito.anyString());

    }

    @Test

    public void testLoggerDebugEnabled() {

    when(loggerMock.isDebugEnabled()).thenReturn(true);

    LoggerDemo loggerDemo = new LoggerDemo();

    loggerDemo.toInt("100");

        verify(loggerMock, times(1)).debug(Mockito.anyString());

    }

    @Test

    public void testLoggerError() {

    //when(loggerMock.isDebugEnabled()).thenReturn(true);

    LoggerDemo loggerDemo = new LoggerDemo();

    loggerDemo.toInt("出错啦");

        verify(loggerMock, times(1)).error(Mockito.anyString());

    }

}

有几个问题:

1. 关于是直接修改logger还是 通过LoggerFactory。 本案例采用了后者,技术要点是对于静态方法的Mock。避免了前者去通过反射修改私有final 变量的复杂性。

2. 由于logger是一个静态变量,在不同用例中的所有类似logger.info的方法调用次数都会被记录。本案例中,各测试用例分别会执行logger.info,所以第一个用例中如果采用以下assert会失败,

    verify(loggerMock, time(1)).info(Mockito.anyString()); 

除非控制用例执行顺序。所以采用了现有的模糊匹配方式。

你可能感兴趣的:(Java_UT_Mock系列之-06Powermock与Logger)