PowerMock简介

PowerMock扩展自Mockito,通过Java反射机制解决Mockito的一些问题,比如:在模拟final,static或者private方法上的不足。

1. Maven依赖


    org.powermock
    powermock-module-junit4
    1.6.4
    test


    org.powermock
    powermock-api-mockito
    1.6.4
    test

为了使用PowerMockito,我们需要在被测试类上添加以下两个注解

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.*")

@PrepareForTest注解中的fullyQualifiedNames代表一组我们想要mock的类的全限定名。在上面的例子中,我们使用了带有通配符的包名,这样,PowerMockito就会准备好com.baeldung.powermockito.introduction包下的所有的类,使他们可以用来mock。

2. 模拟构造器和final方法

本节,我们展示在使用new操作符实例化类时,如何得到一个mock对象,而非真实的对象,并使用mock对象来模拟final方法。

public class CollaboratorWithFinalMethods {
    public final String helloMethod() {
        return "Hello World!";
    }
}

调用无参构造器,返回mock对象

CollaboratorWithFinalMethods mock = mock(CollaboratorWithFinalMethods.class);
whenNew(CollaboratorWithFinalMethods.class).withNoArguments().thenReturn(mock);
CollaboratorWithFinalMethods collaborator = new CollaboratorWithFinalMethods();
verifyNew(CollaboratorWithFinalMethods.class).withNoArguments();

调用final方法

when(collaborator.helloMethod()).thenReturn("Hello Baeldung!");
String welcome = collaborator.helloMethod();
Mockito.verify(collaborator).helloMethod();
assertEquals("Hello Baeldung!", welcome);

3. 模拟static方法

public class CollaboratorWithStaticMethods {
    public static String firstMethod(String name) {
        return "Hello " + name + " !";
    }
 
    public static String secondMethod() {
        return "Hello no one!";
    }
 
    public static String thirdMethod() {
        return "Hello no one again!";
    }
}

为了模拟static方法,需要使用mockStatic注册类

    mockStatic(CollaboratorWithStaticMethods.class);

完整的测试代码如下

    @Test(expected = RuntimeException.class)
    public void givenStaticMethods_whenUsingPowerMockito_thenCorrect() {
        mockStatic(CollaboratorWithStaticMethods.class);

        when(CollaboratorWithStaticMethods.firstMethod(Mockito.anyString())).thenReturn("Hello Baeldung!");
        when(CollaboratorWithStaticMethods.secondMethod()).thenReturn("Nothing special");
        when(CollaboratorWithStaticMethods.thirdMethod()).thenThrow(RuntimeException.class);

        String firstWelcome = CollaboratorWithStaticMethods.firstMethod("Whoever");
        String secondWelcome = CollaboratorWithStaticMethods.firstMethod("Whatever");

        assertEquals("Hello Baeldung!", firstWelcome);
        assertEquals("Hello Baeldung!", secondWelcome);

        verifyStatic(times(2));
        CollaboratorWithStaticMethods.firstMethod(Mockito.anyString());

        verifyStatic(Mockito.never());
        CollaboratorWithStaticMethods.secondMethod();

        CollaboratorWithStaticMethods.thirdMethod();
    }

注意:verifyStatic()要在具体要校验的方法前面

4. 局部校验

public class CollaboratorForPartialMocking {
    public static String staticMethod() {
        return "Hello Baeldung!";
    }
 
    public final String finalMethod() {
        return "Hello Baeldung!";
    }
 
    private String privateMethod() {
        return "Hello Baeldung!";
    }
 
    public String privateMethodCaller() {
        return privateMethod() + " Welcome to the Java world.";
    }
}

4.1 局部模拟static方法

我们使用spy(XXX.class)来局部模拟CollaboratorForPartialMocking类,并为static方法设置预期

spy(CollaboratorForPartialMocking.class);
when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");

校验如下

returnValue = CollaboratorForPartialMocking.staticMethod();
verifyStatic();
CollaboratorForPartialMocking.staticMethod();
assertEquals("I am a static mock method.", returnValue);

4.2 局部模拟final和private方法

我们使用spy(object)来局部模拟CollaboratorForPartialMocking对象

CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking();
CollaboratorForPartialMocking mock = spy(collaborator);

final方法

when(mock.finalMethod()).thenReturn("I am a final mock method.");
returnValue = mock.finalMethod();
verify(mock,times(3)).finalMethod();
assertEquals("I am a final mock method.", returnValue);

private方法

when(mock, "privateMethod").thenReturn("I am a private mock method.");
returnValue = mock.privateMethodCaller();
verifyPrivate(mock).invoke("privateMethod");
assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);

与final方法不同的是,private方法无法直接被调用。PowerMock使用privateMethodCaller作为代理,调用被测试类的private方法。

完整的测试代码如下:

    @Test
    public void givenPartialMocking_whenUsingPowerMockito_thenCorrect() throws Exception {
        String returnValue;

        spy(CollaboratorForPartialMocking.class);
        when(CollaboratorForPartialMocking.staticMethod()).thenReturn("I am a static mock method.");
        returnValue = CollaboratorForPartialMocking.staticMethod();
        verifyStatic();
        CollaboratorForPartialMocking.staticMethod();
        assertEquals("I am a static mock method.", returnValue);

        CollaboratorForPartialMocking collaborator = new CollaboratorForPartialMocking();
        CollaboratorForPartialMocking mock = spy(collaborator);

        when(mock.finalMethod()).thenReturn("I am a final mock method.");
        returnValue = mock.finalMethod();
        verify(mock,times(3)).finalMethod();
        assertEquals("I am a final mock method.", returnValue);

        when(mock, "privateMethod").thenReturn("I am a private mock method.");
        returnValue = mock.privateMethodCaller();
        verifyPrivate(mock).invoke("privateMethod");
        assertEquals("I am a private mock method. Welcome to the Java world.", returnValue);
    }

你可能感兴趣的:(PowerMock简介)