Daniel Kaplan
Daniel Kaplan

Reputation: 67504

How do I completely mock out a class with PowerMockito?

I'm reading this documentation on PowerMockito and it has two main examples:

  1. Mocking static methods
  2. Partially mocking a class

but I want to know how to mock an entire class that's created with new. I am looking for the PowerMockito version of Mockito's mock method. This should be able to replace new Foo() in my production code with a Mockito mock(Foo.class), somehow. Here's what I've tried:

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

    }
}

This test fails with this:

java.lang.Exception: Unexpected exception, expected<java.lang.UnsupportedOperationException> but was<java.lang.IllegalArgumentException>

Here's my production code:

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

}

With my debugger, I can see that the client is not a mock, like I expected.

I've also tried using:

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

But for some reason, that returns a mock that is not completely constructed. I've also tried this:

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

But that gives me a ClassCastException on that line. So, what is the correct way to mock out a class completely with PowerMockito?

Unlike this example implies, the reason I'm trying to mock out HttpClient is so that I can call verify it later.

Upvotes: 1

Views: 7176

Answers (1)

Rohit Jain
Rohit Jain

Reputation: 213391

You don't need to call getMock() method to get back the mocked object. Basically, mock an instance of HttpClient, store it in local variable and use that:

@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);
}

Upvotes: 8

Related Questions