美文网首页
PowerMock 笔记

PowerMock 笔记

作者: oO白眉大虾Oo | 来源:发表于2021-03-10 08:53 被阅读0次

PowerMock 简介

PowerMock 是一个框架,它以更强大的功能扩展了其他模拟库,如 EasyMock 。PowerMock 使用自定义类加载器和字节码操作来实现对静态方法、构造函数、最终类和方法、私有方法、静态初始化器的删除等的模拟。通过使用自定义类加载器,无需对IDE或持续集成服务器进行任何更改,从而简化了采用。PowerMock 旨在使用少量方法和注释扩展现有API,以启用额外功能。目前 PowerMock 支持 EasyMock 和 Mockito。

本篇主要围绕 Mockito 展开.

Mockito

依赖

<properties>
    <powermock.version>2.0.2</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-mockito2</artifactId>
      <version>${powermock.version}</version>
      <scope>test</scope>
   </dependency>
</dependencies>

用法

模拟普通方法

public class NormalMethodClass {
    public String hello() {
        return "hi";
    }
}

@RunWith(PowerMockRunner.class)
public class NormalMethodClassTest {
    @Test
    public void hello() {
        NormalMethodClass normalMethodClass = PowerMockito.mock(NormalMethodClass.class);
        PowerMockito.when(normalMethodClass.hello()).thenReturn("world");
        Assert.assertEquals(normalMethodClass.hello(), "world");
    }
}

模拟静态方法

public final class StaticMethodClass {
    public static boolean m1() {
        return false;
    }
}

@PrepareForTest(StaticMethodClass.class)
@RunWith(PowerMockRunner.class)
public class StaticMethodClassTest {
    @Test
    public void m1() {
        PowerMockito.mockStatic(StaticMethodClass.class);
        PowerMockito.when(StaticMethodClass.m1()).thenReturn(true);
        assertTrue(StaticMethodClass.m1());
    }
}

模拟私有方法

public class PrivateMethodClass {
    public String testM1(String a) {
        System.out.println("testM1:"+ a);
        return m1(a);
    }
    private String m1(String a) {
        System.out.println("m1:"+ a);
        return a;
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(PrivateMethodClass.class)
public class PrivateMethodClassTest {
    @Test
    public void m1() throws Exception {
        String param = "a";
        PrivateMethodClass privateMethodClass = PowerMockito.spy(new PrivateMethodClass());
        PowerMockito.doReturn(param).when(privateMethodClass, "m1", param);
        Assert.assertEquals(privateMethodClass.testM1(param), param);
    }
}

注入模拟

public class NormalMethodClass {

    public String hello() {
        return "hi";
    }

}

public class InjectMockClass {
    private NormalMethodClass normalMethodClass;
    
    public InjectMockClass(NormalMethodClass normalMethodClass) {
        this.normalMethodClass = normalMethodClass;
    }
    
    public String hello() {
        return normalMethodClass.hello();
    }
}

@RunWith(PowerMockRunner.class)
public class InjectMockClassTest {

    @InjectMocks
    private InjectMockClass injectMockClass;
    @Mock
    private NormalMethodClass normalMethodClass;

    @Test
    public void hello() {
        PowerMockito.when(normalMethodClass.hello()).thenReturn("hi");
        Assert.assertEquals("hi", injectMockClass.hello());
    }

}

测试私有方式

public class PrivateMethodClass {

    public String testM1(String a) {
        System.out.println("testM1:"+ a);
        return m1(a);
    }

    private String m1(String a) {
        System.out.println("m1:"+ a);
        return a;
    }

}

@RunWith(PowerMockRunner.class)
@PrepareForTest(PrivateMethodClass.class)
public class CallPrivateMethodClassTest {

    @InjectMocks
    private PrivateMethodClass privateMethodClass;

    @Test
    public void m1() throws Exception {
        String param = "a";
        Method method = PowerMockito.method(PrivateMethodClass.class, "m1", String.class);
        Object res = method.invoke(privateMethodClass, param);
        Assert.assertNotNull(res);
        Assert.assertEquals(res, param);
    }
    
}

注解

@PrepareForTest

需要使用此批注定义的类通常是那些需要字节码操作的类。这包括最终类,具有最终方法,私有方法,静态方法或本机方法的类,应对其进行模拟,以及应在实例化时返回模拟对象的类。

该注释可以放在测试类和单个测试方法上。如果放在一个类中,则该测试类中的所有测试方法都将由PowerMock处理(以实现可测试性)。要为单个方法覆盖此行为,只需在特定的测试方法上放置

如果使用 junit 4.x,注释应始终与 @RunWith(PowerMockRunner.class) 结合使用

@Mock

将字段标记为模拟。

最小化重复的模拟创建代码。

使测试类更具可读性。

NormalMethodClass normalMethodClass = PowerMockito.mock(NormalMethodClass.class);
等价于
@Mock
NormalMethodClass normalMethodClass;

@InjectMocks

将字段标记为注入

允许 mock 和 spy 注入 Mockito 将尝试通过构造函数注入、setter注入或属性注入 mocks。如果以下任何策略失败,则Mockito不会报告失败; 即您必须自己提供依赖项。

相关文章

网友评论

      本文标题:PowerMock 笔记

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