Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Mockito mock object use real the implementation

I had an issue with mocking Apache Http client. The following attempt to create a mock:

DefaultHttpClient httpClient = Mockito.mock(DefaultHttpClient.class);

Fails to create a true mock. The above row gets executed without exceptions, but when I try to stub some behavior:

Mockito.when(httpClient.execute(Mockito.<HttpUriRequest>anyObject())).thenReturn(null);

I get an exception from a method in AbstractHttpClient:

Exception in thread "main" java.lang.IllegalArgumentException: Request must not be null.
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:572)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)

Why is the call to execute inside Mockito.when passed to AbstractHttpClient?

I found a solution to this specific problem: use the interface HttpClient instead of trying to mock the concrete subclass. This is a far better solution in this case, but I am wondering in general what's going on here? Why can't I mock this concrete class properly with Mockito? Is there something special about DefaultHttpClient? Are there other cases where Mockito can't mock concrete classes?

I'm using Mockito 1.8.5, Apache httpclient 4.0.3, Apache http core 4.1, JDK 1.6.0 on OSX

like image 785
auramo Avatar asked Dec 28 '10 17:12

auramo


2 Answers

Several of the methods on AbstractHttpClient are final and thus won't be mocked. IMO, this behavior is the #1 reason not to mock concrete classes.

like image 71
gk5885 Avatar answered Nov 10 '22 12:11

gk5885


Try this syntax (just a sample, not a real code):

import static Mockito.*;
// ...
HttpClient httpClient = mock(HttpClient.class);
doReturn(null).when(httpClient).execute(anyObject()).

See this link for better explanation of the problem/solution: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#doReturn(java.lang.Object)

like image 42
yegor256 Avatar answered Nov 10 '22 12:11

yegor256