Skip to content

Instantly share code, notes, and snippets.

@jhannes
Created July 16, 2012 20:39
Show Gist options
  • Save jhannes/3124900 to your computer and use it in GitHub Desktop.
Save jhannes/3124900 to your computer and use it in GitHub Desktop.
Test driving external dependencies
public class CurrencyPublisherTest {
private SubscriptionRepository subscriptionRepository = mock(SubscriptionRepository.class);
private EmailService emailService = mock(EmailService.class);
private CurrencyPublisher publisher = new CurrencyPublisher();
private CurrencyService currencyService = mock(CurrencyService.class);
private GeolocationService geolocationService = mock(GeolocationService.class);
@Test
public void shouldPublishCurrency() throws Exception {
Subscription subscription = TestDataFactory.randomSubscription();
String location = TestDataFactory.randomCountry();
String currency = TestDataFactory.randomCurrency();
double exchangeRate = subscription.getLowLimit() * 0.9;
when(subscriptionRepository.findPendingSubscriptions()).thenReturn(Arrays.asList(subscription));
when(geolocationService.getCountryByIp(subscription.getIpAddress())).thenReturn(location);
when(currencyService.getCurrency(location)).thenReturn(currency);
when(currencyService.getExchangeRateFromUSD(currency)).thenReturn(exchangeRate);
publisher.runPeriodically();
verify(emailService).publishCurrencyAlert(subscription, currency, exchangeRate);
}
@Before
public void setupPublisher() {
publisher.setSubscriptionRepository(subscriptionRepository);
publisher.setGeolocationService(geolocationService);
publisher.setCurrencyService(currencyService);
publisher.setEmailService(emailService);
}
}
public class GeolocationServiceLiveTest {
@Test
public void shouldFindLocation() throws Exception {
GeolocationService wsClient = new GeolocationServiceWsClient("http://www.webservicex.net/geoipservice.asmx");
assertThat(wsClient.getCountryByIp("80.203.105.247")).isEqualTo("Norway");
}
}
public class GeolocationServiceStub extends HttpServlet {
private Map<String,String> locations = new HashMap<String, String>();
public void addLocation(String ipAddress, String country) {
locations.put(ipAddress, country);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
String ipAddress = $(req.getReader()).xpath("/Envelope/Body/GetGeoIP/IPAddress").text();
String location = locations.get(ipAddress);
createResponse(location).write(resp.getOutputStream());
} catch (Exception e) {
throw new RuntimeException("Exception at server " + e);
}
}
}
public class GeolocationServiceStubHttpTest {
@Test
public void shouldAnswerCountry() throws Exception {
GeolocationServiceStub stub = new GeolocationServiceStub();
stub.addLocation("80.203.105.247", "Norway");
Server server = new Server(0);
ServletContextHandler context = new ServletContextHandler();
context.addServlet(new ServletHolder(stub), "/GeoService");
server.setHandler(context);
server.start();
String url = "http://localhost:" + server.getConnectors()[0].getLocalPort();
GeolocationService wsClient = new GeolocationServiceWsClient(url + "/GeoService");
String location = wsClient.getCountryByIp("80.203.105.247");
assertThat(location).isEqualTo("Norway");
}
}
public class GeolocationServiceWsClient implements GeolocationService {
private Validator validator;
private UrlSoapEndpoint endpoint;
public GeolocationServiceWsClient(String url) throws Exception {
this.endpoint = new UrlSoapEndpoint(url);
validator = createValidator();
}
@Override
public String getCountryByIp(String ipAddress) throws Exception {
Element request = createGeoIpRequest(ipAddress);
Document soapRequest = createSoapEnvelope(request);
validateXml(soapRequest);
Document soapResponse = endpoint.postRequest(getSOAPAction(), soapRequest);
validateXml(soapResponse);
return parseGeoIpResponse(soapResponse);
}
private void validateXml(Document soapMessage) throws Exception {
validator.validate(toXmlSource(soapMessage));
}
protected Validator createValidator() throws SAXException {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new Source[] {
new StreamSource(getClass().getResource("/geoipservice.xsd").toExternalForm()),
new StreamSource(getClass().getResource("/soap.xsd").toExternalForm()),
});
return schema.newValidator();
}
private Document createSoapEnvelope(Element request) throws Exception {
return $("S:Envelope",
$("S:Body", request)).document();
}
private Element createGeoIpRequest(String ipAddress) throws Exception {
return $("wsx:GetGeoIP", $("wsx:IPAddress", ipAddress)).get(0);
}
private String parseGeoIpResponse(Element response) {
// TODO
return null;
}
private Source toXmlSource(Document document) throws Exception {
return new StreamSource(new StringReader($(document).toString()));
}
}
public class UrlSoapEndpoint {
private final String url;
public UrlSoapEndpoint(String url) {
this.url = url;
}
public Document postRequest(String soapAction, Document soapRequest) throws Exception {
URL httpUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.addRequestProperty("SOAPAction", soapAction);
connection.addRequestProperty("Content-Type", "text/xml");
$(soapRequest).write(connection.getOutputStream());
int responseCode = connection.getResponseCode();
if (responseCode != 200) {
throw new RuntimeException("Something went terribly wrong: " + connection.getResponseMessage());
}
return $(connection.getInputStream()).document();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment