美文网首页工作相关android技术专栏Android进阶之旅
使用PowerMock框架进行静态方法的测试

使用PowerMock框架进行静态方法的测试

作者: 健谈的Boris | 来源:发表于2017-09-11 16:26 被阅读1679次

    简介

    一般来说,Java中的静态方法无法用传统的Jmock进行单测,这也就给研发人员和测试人员造成了一定的困扰。本文介绍一种使用PowerMock执行静态方法单元测试的手段,其实网上也有使用如Mockito的方法,大家可以自行搜索。

    静态方法的测试手段

    其实从一个测试人员的角度看,静态方法的测试并不比非静态方法难,比如下面这个例子:

    public final class StringUtil {
        public static String nullSafeTrim(String s) {
            return s == null ? "" : s.trim();
        }
    }
    

    写StringUtil的单测case与一般的代码类似,在代码的before,代码中,或after放你的单测case。

    public class StringUtilTest {
     
       @Test public void shouldHandleNull() {
          assertEquals("", StringUtil.nullSafeTrim(null));
       }
     
       @Test public void shouldHandleEmptyString() {
          assertEquals("", StringUtil.nullSafeTrim(""));
       }
     
       @Test public void shouldTrimWhiteSpace() {
          assertEquals("foo bar", StringUtil.nullSafeTrim("\t\n\r foo bar \r\n\t"));
       }
     
    }
    

    如果静态类有依赖的类,那么如果此依赖类可以通过接口进行抽象,则可以使用setter诸如,例如:

    public interface Dependency {
       void doSomething();
    }
     
    public final class StringUtil {
     
       private static Dependency dependency;
     
       public static void setDependency(Dependency d) {
          dependency = d;
       }
       ...
    }
    

    如果要进行mock的话:

    public class DependencyMock implements Dependency {
     
       public void doSomething() {
       }
    }
     
    public class StringUtilTest {
     
       @Before public void setUp() {
          StringUtil.setDependency( new DependencyMock() );
       }
       ...
    }
    

    利用PowerMock测试静态方法

    PowerMock是一个JUnit扩展,它利用了EasyMock和Mockito模拟静态method的方法对Java中的静态method进行Mock,而且它还有更多的功能(详见github/powermock)。

    例如,现在有如下程序:

    public class Calculator {
     
       public int add(int a, int b) {
          return MathUtil.addInteger(a, b);
       }
    }
     
    public abstract class MathUtil {
     
       public static final int addInteger(int a, int b) {
          return a + b;
       }
     
       private MathUtil() {}
    }
    

    如果我们想Mock MathUtil的话:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest( MathUtil.class ) //准备被mock的类,在这里为MathUtil.class
    public class CalculatorTest {
     
       /** Unit under test. */
       private Calculator calc;
     
       @Before public void setUp() {
          calc = new Calculator();
          
          //调用PowerMockito.mockStatic()
          PowerMockito.mockStatic(MathUtil.class);
          //使用PowerMockito.when()定义mock动作
          PowerMockito.when(MathUtil.addInteger(1, 1)).thenReturn(0);
          PowerMockito.when(MathUtil.addInteger(2, 2)).thenReturn(1);
       }
     
       @Test public void shouldCalculateInAStrangeWay() {
          assertEquals(0, calc.add(1, 1) );
          assertEquals(1, calc.add(2, 2) );
       }
    }
    
    注意,还要把依赖加入pom.xml(假设用的是Maven)就可以执行了。
    <properties>
        <powermock.version>1.4.9</powermock.version>
    </properties>
     
    <dependencies>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>1.8.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    相关文章

      网友评论

        本文标题:使用PowerMock框架进行静态方法的测试

        本文链接:https://www.haomeiwen.com/subject/mgsfsxtx.html