如何使用 PowerMockito 完全模拟 class?
How do I completely mock out a class with PowerMockito?
我正在阅读这篇文章 documentation on PowerMockito,其中有两个主要示例:
- 模拟静态方法
- 部分嘲笑 class
但我想知道如何模拟使用 new
创建的整个 class。 我正在寻找 Mockito 的 mock
方法 的 PowerMockito 版本。这应该能够以某种方式用 Mockito mock(Foo.class)
替换我的生产代码中的 new Foo()
。这是我尝试过的:
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();
}
}
这个测试失败了:
java.lang.Exception: Unexpected exception, expected<java.lang.UnsupportedOperationException> but was<java.lang.IllegalArgumentException>
这是我的生产代码:
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);
}
}
使用我的调试器,我可以看到 client
不是我预期的模拟。
我也试过使用:
Object mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().getMock();
但由于某种原因,returns 一个未完全构建的模拟。我也试过这个:
HttpClient mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().thenReturn(mock(HttpClient.class)).getMock();
但这给了我在那条线上的 [=21=]。那么,使用 PowerMockito 完全模拟 class 的正确方法是什么?
与此示例不同,我尝试模拟 HttpClient 的原因是我可以稍后调用 verify
它。
您不需要调用 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);
}
我正在阅读这篇文章 documentation on PowerMockito,其中有两个主要示例:
- 模拟静态方法
- 部分嘲笑 class
但我想知道如何模拟使用 new
创建的整个 class。 我正在寻找 Mockito 的 mock
方法 的 PowerMockito 版本。这应该能够以某种方式用 Mockito mock(Foo.class)
替换我的生产代码中的 new Foo()
。这是我尝试过的:
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();
}
}
这个测试失败了:
java.lang.Exception: Unexpected exception, expected<java.lang.UnsupportedOperationException> but was<java.lang.IllegalArgumentException>
这是我的生产代码:
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);
}
}
使用我的调试器,我可以看到 client
不是我预期的模拟。
我也试过使用:
Object mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().getMock();
但由于某种原因,returns 一个未完全构建的模拟。我也试过这个:
HttpClient mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().thenReturn(mock(HttpClient.class)).getMock();
但这给了我在那条线上的 [=21=]。那么,使用 PowerMockito 完全模拟 class 的正确方法是什么?
与此示例不同,我尝试模拟 HttpClient 的原因是我可以稍后调用 verify
它。
您不需要调用 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);
}