Reputation: 55424
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.
Upvotes: 6
Views: 26383
Reputation: 11
Use xml mimic stub server, that can simulate static http response based on request parameters, headers, etc. It is very simple to configure and use it.
http://xmlmimic.sourceforge.net/ http://sourceforge.net/projects/xmlmimic/
Upvotes: 0
Reputation: 245
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();
}
Upvotes: 5
Reputation: 8582
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.
Upvotes: 3
Reputation: 19881
You can wrap that code in some class and have WebClient.getUrl() and then mock (e.g. jmock) that method to return stored files - say
expectation {
oneOf("https://someurl/"), will(returnValue(someHTML));
}
Upvotes: 2
Reputation: 364
To what extend are you interested in mocking this "Get" call, because if you are looking for a general purpose mocking framework for Java which integrates well with JUnit and allows to setup expectations which are automatically asserted when incorporated into a JUnit suite, then you really ought to take a look at jMock.
Now without more code, it's hard to determine whether this is actually what you are looking for, but a (somewhat useless) example, of something similar to the example code you wrote, would go something like this:
class GetMethodTest {
@Rule public JUnitRuleMockery context = new JunitRuleMockery();
@Test
public void testGetMethod() throws Exception {
// Setup mocked object with expectations
final GetMethod method = context.mock(GetMethod.class);
context.checking(new Expectations() {{
oneOf (method).getResponseBodyAsString();
will(returnValue("Response text goes here"));
}});
// Now do the checking against mocked object
String content = method.getResponseBodyAsString();
}
}
Upvotes: 1
Reputation: 120158
If you are writing a unit test, you dont want any external dependencies. from the api,
GetMethod
extends
HttpMethod
so you can easily mock it with your favorite mocking library. Your
method.getResponseBodyAsString()
call can be mocked to return any data you want.
Upvotes: 2
Reputation: 15063
You could always launch a thttpd
server as part of your unit test to serve the requests locally. Though, ideally, you have a well tested GetMethod
, and then you can just mock it, and not have to actually have a remote server around for ALL of your tests.
Resources
Upvotes: 1
Reputation: 54884
Take a look at JWebUnit http://jwebunit.sourceforge.net/
Here is an example of a test...Its really quite intuitive.
public class ExampleWebTestCase extends WebTestCase {
public void setUp() {
super.setUp();
setBaseUrl("http://localhost:8080/test");
}
public void test1() {
beginAt("/home");
clickLink("login");
assertTitleEquals("Login");
setTextField("username", "test");
setTextField("password", "test123");
submit();
assertTitleEquals("Welcome, test!");
}
}
Upvotes: 1