Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing http request/response in android

Tags:

android

In my android application I'm using Sprint Rest Template for making API call to the webserver. But in test project where I test method for making requests with String ResT Template I don't want to send real HTTP requests.

Is there any way to mock HTTP requests sent by rest template? Can I provide my preferred response?

like image 931
Armen Avatar asked Jan 06 '14 19:01

Armen


1 Answers

Yes, I'm doing something like the following:

In your build.gradle add the following:

androidTestCompile("org.springframework:spring-test:3.2.8.RELEASE") {
    exclude module: "spring-core"
}

You want the exclusion to avoid this exception

java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation

Then in your test do something like the following:

public void testService() throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        PeopleService peopleService = new PeopleService(restTemplate);

        MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
        mockServer.expect(requestTo("http://localhost:3000/api/v1-DEV/people"))
                .andExpect(method(HttpMethod.GET))
                .andExpect(header("Authorization", "Bearer TEST_TOKEN"))
                .andRespond(withSuccess("JSON DATA HERE", MediaType.APPLICATION_JSON));

        People people = peopleService.getPeople();

        mockServer.verify();

        assertThat(people).isNotNull();
        //Other assertions
}

Here is an example from Spring (http://docs.spring.io/spring/docs/3.2.7.RELEASE/javadoc-api/org/springframework/test/web/client/MockRestServiceServer.html):

 RestTemplate restTemplate = new RestTemplate()
 MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

 mockServer.expect(requestTo("/hotels/42")).andExpect(method(HttpMethod.GET))
     .andRespond(withSuccess("{ \"id\" : \"42\", \"name\" : \"Holiday Inn\"}", MediaType.APPLICATION_JSON));

 Hotel hotel = restTemplate.getForObject("/hotels/{id}", Hotel.class, 42);
 // Use the hotel instance...

 mockServer.verify();

Another way to do it is by using Mockito. Include the following in your build.gradle:

androidTestCompile "com.google.dexmaker:dexmaker:1.0"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.0"
androidTestCompile "org.mockito:mockito-core:1.9.5"

You'll need each of the above to use Mockito properly.

Then in your test do the following:

public class TestClass extends InstrumentationTestCase {
    @Mock
    private RestTemplate restTemplate;

    protected void setUp() throws Exception {
        super.setUp();

        initMocks(this);
    }

    public void testWithMockRestTemplate() throws Exception {
        Hotel expectedHotel = new Hotel("Fake Hotel From Mocked Rest Template");
        when(restTemplate.getForObject("/hotels/{id}", Hotel.class, 42).thenReturn(expectedHotel);

        Hotel hotel = restTemplate.getForObject("/hotels/{id}", Hotel.class, 42);

        assertThat(hotel).isEqualTo(expectedHotel);

    }
}

Hope this helps!

like image 100
vincentjames501 Avatar answered Sep 17 '22 14:09

vincentjames501