如何使用 PowerMockito 完全模拟一个类?

Dan*_*lan 1 java unit-testing mockito powermock powermockito

我正在阅读有关 PowerMockito 的文档,它有两个主要示例:

  1. 模拟静态方法
  2. 部分嘲笑一个班级

但我想知道如何模拟使用new. 我正在寻找 Mockitomock方法的 PowerMockito 版本。这应该能够以某种方式new Foo()用 Mockito替换我的生产代码mock(Foo.class)。这是我尝试过的:

import com.PowerMockitoProduction;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

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


@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerMockitoProduction.class)
public class PowerMockitoTest {

    @Test(expected = UnsupportedOperationException.class)
    public void test() throws Exception {

        HttpClient mock = PowerMockito.mock(HttpClient.class);
        when(mock.executeMethod(any(HttpMethod.class))).thenThrow(UnsupportedOperationException.class);

        new PowerMockitoProduction().createClient();

    }
}
Run Code Online (Sandbox Code Playgroud)

这个测试失败了:

java.lang.Exception: Unexpected exception, expected<java.lang.UnsupportedOperationException> but was<java.lang.IllegalArgumentException>
Run Code Online (Sandbox Code Playgroud)

这是我的生产代码:

package com;

import org.apache.commons.httpclient.HttpClient;

import java.io.IOException;


public class PowerMockitoProduction {

    public void createClient() throws IOException {
        HttpClient client = new HttpClient();
        client.executeMethod(null);
        System.out.println(client);
    }

}
Run Code Online (Sandbox Code Playgroud)

使用我的调试器,我可以看到这client不是模拟,就像我预期的那样。

我也试过使用:

Object mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().getMock();
Run Code Online (Sandbox Code Playgroud)

但出于某种原因,这会返回一个未完全构造的模拟。我也试过这个:

HttpClient mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().thenReturn(mock(HttpClient.class)).getMock();
Run Code Online (Sandbox Code Playgroud)

但这给了我一个ClassCastException在线。那么,使用 PowerMockito 完全模拟一个类的正确方法是什么?

与这个例子暗示的不同,我试图模拟 HttpClient 的原因是我可以verify稍后调用它。

Roh*_*ain 7

您不需要调用getMock()方法来取回模拟对象。基本上,模拟 的实例HttpClient,将其存储在局部变量中并使用它:

@Test(expected=UnsupportedOperationException.class)
public void test() {
    HttpClient httpClient = mock(HttpClient.class);
    PowerMockito.whenNew(HttpClient.class).withNoArguments().thenReturn(httpClient);
    when(httpClient.executeMethod(any(HttpMethod.class))).thenThrow(UnsupportedOperationException.class);

    new PowerMockitoProduction().createClient();
    verify(httpClient).executeMethod(null);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的。您必须将模拟实例存储为本地或实例变量,并使用它。 (2认同)