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

时间:2015-02-23 20:35:36

标签: java unit-testing mockito powermock powermockito

我正在阅读此documentation on PowerMockito,它有两个主要的例子:

  1. 模拟静态方法
  2. 部分嘲笑一个班级
  3. 但我想知道如何模拟用new创建的整个班级。 我正在寻找Mockito的mock方法的PowerMockito版本。这应该能够以某种方式用Mockito new Foo()替换生产代码中的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();
    
        }
    }
    

    此测试失败了:

    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();
    

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

    HttpClient mock = PowerMockito.whenNew(HttpClient.class).withNoArguments().thenReturn(mock(HttpClient.class)).getMock();
    

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

    与此示例不同,我试图模仿HttpClient的原因是我可以稍后调用verify

1 个答案:

答案 0 :(得分:4)

您无需调用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);
}