I using Spring Android Rest Template to perform HTTP request. I was testing like so :
package com.mnubo.platform.android.sdk.internal.user.services.impl;
import com.mnubo.platform.android.sdk.models.users.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.client.MockRestServiceServer;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
@RunWith(RobolectricTestRunner.class)
@Config(emulateSdk = 18)
public class DummyTest {
private MyApiImpl myApi;
private MockRestServiceServer myapiMockServer;
@Before
public void setUp() throws Exception {
myApi = new MyApiImpl("ACCESS_TOKEN");//break here
myapiMockServer = MockRestServiceServer.createServer(myApi.getRestTemplate());
}
@Test
public void testRestClient() throws Exception {
final User expectedUser = new User();
expectedUser.setUsername("test");
expectedUser.setLastname("lastname");
myapiMockServer.expect(requestTo("http://my-service.com/user/test"))
.andExpect(method(GET))
.andRespond(withSuccess(this.convertToJsonString(expectedUser), APPLICATION_JSON_UTF8));
User user = myApi.userOperations().getUser("test");
userMockServer.verify();
}
}
All of this was working correctly using the RoboelectricTestRunner. But, yesterday Android Studio updated and asked me to update the build tool version to 1.1.0. (com.android.tools.build:gradle:1.1.0).
This version now include supports for Unit testing. See https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support
The problem : I can't create MyApiImpl
anymore because it creates a RestTemplate. This RestTemplate use org.springframework.http.client.HttpComponentsClientHttpRequestFactory and in this class constructor, methods from the org.apache.http package are used.
These methods raised an exception : Eg: Method getSocketFactory in org.apache.http.conn.scheme.PlainSocketFactory
Well, I mocked successfully the getSocketFactory using PowerMock but then I had to mock the register
method of SchemeRegistry that is only locally accessible from the constructor (source).
So I gave up trying to mock all of the shenanigans happening inside the RestTemplate and decided to directly mock the RestTemplate.
I need help to mock it correctly so that the MockRestServiceServer
can still be used in my test, because right now, the myapiMockServer.verify()
assertion fails.
Update
I'm still unable to use the MockRestServiceServer
to test my Api, but I managed to test each individual OperationImpl
using a mock of the RestTemplate
like so :
public class DummyOperationTest {
private DummyOperation dummyOperation;
private RestTemplate mockedRestTemplate = mock(RestTemplate.class);
@Before
public void setUp() throws Exception {
super.setUp();
dummyOperation = new DummyOperationImpl(PLATFORM_BASE_URL, mockedRestTemplate);
}
@Test
public void test() throws Exception {
String calledUrl = PLATFORM_BASE_URL + "/objects?update_if_exists=true";
when(mockedRestTemplate.postForObject(calledUrl, expectedSmartObject, SmartObject.class)).thenReturn(expectedSmartObject);
smartObjectService.create(expectedSmartObject, true);
verify(mockedRestTemplate, atMost(1)).postForObject(calledUrl, expectedSmartObject, SmartObject.class);
}
}
Unfortunately, this still doesn't test the whole request execution. I can't validate that oAuth authentication is correctly added to the headers, or if the conversion of the server response is correct.