Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mock https request in java

Tags:

java

http

mocking

Let's say I'm writing an application and I need to be able to do something like this:

String url = "https://someurl/";
GetMethod method = new GetMethod(URLEncoder.encode(url));
String content = method.getResponseBodyAsString();

Is there a way to provide a mock server that would let me handle the https request? What I'm looking for is a way to write unit tests, but I need to be able to mock the part that actually goes out to https://someurl so I can get a known response back.

like image 781
dcp Avatar asked Oct 04 '10 17:10

dcp


2 Answers

Take a look at jadler (http://jadler.net), an http stubbing/mocking library I've been working on for some time. The 1.0.0 stable version has been just released, it should provide the capabilities you requested:

@Test
public void getAccount() {

    onRequest()
        .havingMethodEqualTo("GET")
        .havingURIEqualTo("/accounts/1")
        .havingBody(isEmptyOrNullString())
        .havingHeaderEqualTo("Accept", "application/json")
    .respond()
        .withTimeout(2, SECONDS)
        .withStatus(200)
        .withBody("{\"account\":{\"id\" : 1}}")
        .withEncoding(Charset.forName("UTF-8"))
        .withContentType("application/json; charset=UTF-8");

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port());
    final Account account = service.getAccount(1);

    assertThat(account, is(notNullValue()));
    assertThat(account.getId(), is(1));
}


@Test
public void deleteAccount() {

    onRequest()
        .havingMethodEqualTo("DELETE")
        .havingPathEqualTo("/accounts/1")
    .respond()
        .withStatus(204);

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port());
    service.deleteAccount(1);

    verifyThatRequest()
        .havingMethodEqualTo("DELETE")
        .havingPathEqualTo("/accounts/1")
    .receivedOnce();
}
like image 165
Jan Dudek Avatar answered Oct 12 '22 02:10

Jan Dudek


You essentially have two options:

1. Abstract the call to the framework and test this.

E.g. refactor the code to allow you to inject a mock implementation at some point. There are many ways to do this. e.g. create a getUrlAsString() and mock that. (also suggested above). Or create a url getter factory that returns a GetMethod object. The factory then can be mocked.

2. Start up a app server as part of the test and then run your method against it. (This will be more of an integration test)

This can be achieved in an number of ways. This can be external to the test e.g. the maven jetty plugin. or the test can programmatically start up the server. see: http://docs.codehaus.org/display/JETTY/Embedding+Jetty

Running it over https will complicate this but it will still be possible with self signed certs. But I'd ask yourself - what exactly you want to test? I doubt you actually need to test https functionality, its a proven technology.

Personally I'd go for option 1 - you are attempting to test functionality of an external library. That is usually unnecessary. Also it's good practice to abstract out your dependencies to external libraries.

Hope this helps.

like image 33
Pablojim Avatar answered Oct 12 '22 00:10

Pablojim