Mock URL

1,978 views
Skip to first unread message

MohanR

unread,
Oct 1, 2013, 2:46:11 AM10/1/13
to powe...@googlegroups.com
Hi,
             I have this class that tries to mock a URL connection. It is a known example. Get an error.

java.lang.AssertionError: Wanted but not invoked java.net.URL(
    "http",
    "localhost",
    80,
    "POST"
);
Actually, there were zero interactions with this mock.
 
Thanks,
Mohan

public class TestPrintServer {

    /**
     * URL mock.
     */
    private URL url;

    /**
     * HttpURLConnection mock.
     */
    private HttpURLConnection connection;

    private NettyServer instance = new NettyServer();

private ByteArrayInputStream input = new ByteArrayInputStream( 
new Gson().toJson(
new PassBook()).getBytes() );

private ByteArrayOutputStream output = new ByteArrayOutputStream();

    @Before
    public void setUp() throws Exception
    {
        this.url = PowerMockito.mock(URL.class);
        this.connection = PowerMockito.mock(HttpURLConnection.class);

        PowerMockito.whenNew(URL.class).
        withArguments( "http", "localhost", 80, "POST" ).thenReturn(this.url);
    }

    @Test
    public void testDoPost() throws Exception
    {
        PowerMockito.doReturn(this.connection).when(this.url).openConnection();
        PowerMockito.doReturn(this.output).when(this.connection).getOutputStream();
        PowerMockito.doReturn(this.input).when(this.connection).getInputStream();


        PowerMockito.verifyNew(URL.class);
        final String response = this.instance.doPost("POST", new Gson().toJson(
new PassBook()));

        // Mockito.verify(this.url).openConnection(); // cannot be verified (mockito limitation) 
        Mockito.verify(this.connection).getOutputStream();
        Mockito.verify(this.connection).setRequestMethod("POST");
        Mockito.verify(this.connection).setRequestProperty("Content-Type", "application/xml");
        Mockito.verify(this.connection).setUseCaches(false);
        Mockito.verify(this.connection).setDoInput(true);
        Mockito.verify(this.connection).setDoOutput(true);
        Mockito.verify(this.connection).getInputStream();

        JsonParser parser = new JsonParser();
        //assertEquals(this.output, input);    
    }
    

class PassBook{
   
    private String name = "Test";
   
    private double balance = 17989.99;
    }
@Data class NettyServer{
   private String doPost(String string, String input) throws MalformedURLException {
       new URL("http", "localhost", 80, "POST");
return "{\"status\":1}";
}

}
}

Johan Haleby

unread,
Oct 1, 2013, 3:13:33 AM10/1/13
to powe...@googlegroups.com
I can't see that you prepare anything for test using the @PrepareForTest annotation? In case of system classes you need to use this approach.

/Johan


--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To unsubscribe from this group and stop receiving emails from it, send an email to powermock+...@googlegroups.com.
To post to this group, send email to powe...@googlegroups.com.
Visit this group at http://groups.google.com/group/powermock.
For more options, visit https://groups.google.com/groups/opt_out.

MohanR

unread,
Oct 1, 2013, 3:37:53 AM10/1/13
to powe...@googlegroups.com
@RunWith(PowerMockRunner.class)
@PrepareForTest({ NettyServer.class, URL.class, HttpURLConnection.class })
public class TestPrintServer {

That is done.

Thanks.

Johan Haleby

unread,
Oct 1, 2013, 5:52:57 AM10/1/13
to powe...@googlegroups.com
Are you trying to mock stuff the "doPost" method in the PassBook class? You try to verify a field in your test code called this.url but it's never set from the actual code!? That won't work.

MohanR

unread,
Oct 1, 2013, 7:15:48 AM10/1/13
to powe...@googlegroups.com
Hi,
            I was trying to mock a URL so that when I open a mock connection(  new URL("http", "localhost", 80, "POST").openConnection();)
and post I get a particular response. I am trying to do this with PowerMock and PowerMockito.

Thanks.
 
@RunWith(PowerMockRunner.class)
@PrepareForTest({ TestPrintServer.class})
public class TestPrintServer {

    private NettyServer instance = new NettyServer();

private ByteArrayInputStream input = new ByteArrayInputStream( 
new Gson().toJson(
new PassBook()).getBytes() );

    private URL url;

    private InputStream inputStream;

private ByteArrayOutputStream output = new ByteArrayOutputStream();

@Before
    public void setUp() throws MalformedURLException {
            //url = createMock(URL.class);
    }
@Test
    public void testNetty() throws Exception {
        //new URL("http", "localhost", 80, "POST").openConnection();
   }


class PassBook{
   
    private String name = "Test";
   
    private double balance = 17989.99;
    }
}

class NettyServer{
    public String doPost(String string, String input) throws IOException {
  return "{\"status\":1}";
}

}

Johan Haleby

unread,
Oct 2, 2013, 1:39:44 AM10/2/13
to powe...@googlegroups.com
I see, you can mock new instances of URL if you do something like this:

// Given
final URL url = mock(URL.class);
whenNew(URL.class).withArguments("some_url").thenReturn(url);

// When
final URL actual = new SystemClassUser().newURL("some_url");

// Then
assertSame(url, actual);

The newURL method simply looks like this:
public URL newURL(String anUrl) throws MalformedURLException {
        return new URL(anUrl);
}

You need to make sure that your equivalent of SystemClassUser.class is prepared for test for this to work.


/Johan


MohanR

unread,
Oct 3, 2013, 2:13:43 AM10/3/13
to powe...@googlegroups.com
This results is this trace 

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class replica.java.net.URL$$PowerMock0
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:100)

 
@RunWith(PowerMockRunner.class)
@PrepareForTest({ PrintPassBook.class, URL.class})
public class TestPrintServer {

    private String realUrl;
    
    public final URL url = PowerMockito.mock(URL.class);

   @Before
    public void setUp() throws Exception {
 
         realUrl = "http://localhost:9090";
         
         PowerMockito.whenNew(URL.class).withArguments( realUrl ).thenReturn(url);

    }
@Test
public void testUrl() throws MalformedURLException{
        final URL actual = new PrintPassBook().newURL(realUrl);

        Assert.assertSame(url, actual);
}
}

public class PrintPassBook {

Johan Haleby

unread,
Oct 3, 2013, 2:49:28 AM10/3/13
to powe...@googlegroups.com
I don't think you can call PowerMockito.mock(URL.class) during field initialization. Try move it to the setup method and if that doesn't work then move it to the testUrl method.

Regards,
/Johan




MohanR

unread,
Oct 4, 2013, 3:20:22 AM10/4/13
to powe...@googlegroups.com
Thanks. It  Worked.

Mohan

Johan Haleby

unread,
Oct 4, 2013, 3:56:39 AM10/4/13
to powe...@googlegroups.com
Great!
Reply all
Reply to author
Forward
0 new messages