美文网首页
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