Which Scala framework to use for testing REST services? - unit-testing

I'd like to use Spec2 and Scala to test a REST service that was build using Java. I looked at Spray but it seams like you have to build your application using Spray in order to test it using SprayTest. I also found this thread but it's not really what I'm looking for.
Any other ideas?

We have successfully been testing all of our REST APIs using Specs2 and the Dispatch library (https://dispatchhttp.org/Dispatch.html). Dispatch takes a little bit of time to get your head around, but once you understand how it composes everything together with various operators you can test a simple REST service with a couple of lines of code.
Here's a couple of test cases from out recent project:
def issueErrorStatus = {
val requestBody = "msisdn=447777666666&message=Some test message"
val req = url("http://localhost:%d/otac/issue".format(port)) <<
(requestBody, "application/x-www-form-urlencoded")
val response = Http.when(_ == 400)(req <:< (touchPointHeaders) as_str)
response must_== """{"error":"Message must contain an {OTAC} place holder"}"""
}
def checkOtac = {
val req = url("http://localhost:%d/otac/check".format(port)) <<?
Vector(("msisdn" -> "447777123456"))
val response = Http(req <:< (touchPointHeaders) as_str)
response must_== """{"status":"Present","reissueAllowed":true}"""
}
The first test makes a post request, the second a get request. We also have some more complex tests that parse the response JSON string through the lift-json parser so that we can assert agains the document more easily. The above tests are just checking some simple error/status cases.
There's also a dispatch-reboot project underway that has a simplified API and works with async connections. Not sure how stable it is yet though.

In my last projects I used AsyncHttpClient and Jersey Client for testing REST services and I can recommend both of them. For async operations the former is better (I don't know if jersey client
supports async operations at all).
They are written in Java and have (to my knowledge) no Scala-API.

Related

How do I retrieve body of client request in a spring webflux unit test?

I have a #Service which uses a WebClient to return a Mono<Something>. I want to test that the service adds the right data to the request - headers, URI, body. My test's approach is to inject a mocked WebClient.Builder into the service, and provide a WebClient with a custom exchange function:
#BeforeEach
void preProgramWebClientBuilder() {
webClient = WebClient.builder()
.baseUrl(TEST_REMOTE_BASE_URL)
.exchangeFunction(clientRequest -> {
// ...
}).build();
// webClientBuilder is the mockito-managed mock
when(webClientBuilder.baseUrl(anyString())).thenReturn(webClientBuilder);
when(webClientBuilder.build()).thenReturn(webClient);
}
This works well, for checking request host/path/query parameters/headers, with the exchange function either performing the checks itself, or setting the clientRequest aside for the test to do the checks. But I have not found a way to extract the body from the clientRequest object, to perform assertions on it.
Fully mocking the WebClient yields some ugly test initialization code, which I'd like to avoid. Is there a decent way to extract the request body from the clientRequest?
Just to mention it: I don't see how I can use a StepVerifier here. StepVerifier expects to get the Publisher to verify - and getting the body of the request as a publisher is exactly what I haven't managed to do. A WebTestClient has the same problem - I can perform a request with it, then do assertions on the response, but I can't substitute it for the regular WebClient in the service in order to perform assertions on the request emitted by the service.

Mock Microsoft Application Insights API

I have an application which writes to App INsights using custom traces/metrics and also using REST API for reading data on to dashboard.
My questions is for my unit testing can I mock both custom traces(TelemetryClient) and REST API?
I see REST API has a DEMO version but provides random information. It would be helpful if i could setup a DEMO instrumentation key to write to and read from it for unit testing. Let me know.
My proffered approach would be (as for any external component) to create some sort of wrapper around Telemetry Client and then it would be easy to mock it or replace it later if needed.
The other approach I would try is to use TelemetryClient constructor overload with TelemetryConfiguration and mock TelemetryChannel.
var client = new TelemetryClient(
new TelemetryConfiguration
{
TelemetryChannel = new MOCK...
});
Application Insights has an example of mocking TelemetryClient by using a StubTelemetryChannel.
var configuration = new TelemetryConfiguration();
this.sendItems = new List<ITelemetry>();
configuration.TelemetryChannel = new StubTelemetryChannel { OnSend = item => this.sendItems.Add(item) };
configuration.InstrumentationKey = Guid.NewGuid().ToString();
configuration.TelemetryInitializers.Add(new OperationCorrelationTelemetryInitializer());
this.telemetryClient = new TelemetryClient(configuration);
Instead of mocking things out, it might be better to go with your second idea and actually create another application insights resource, and use the instrumentation key for that resource in the unit tests. there's a blog post with information about using multiple environments that should head you in the right direction.
I'd suggest you even do something like that for developer/debug builds as well, so that only your "production" telemetry goes to your real instance, and then all dev/test telemetry goes to another resource instead.

How to Unit Test (mock class) in Groovy with nested closures?

I modified the code from here to look very much like the code I have and am trying to create Unit Tests for. While I would like to ask "what is the best way" to test this, I will be quite satisfied with any way to create a decent Unit Test! I looked at Spock, GroovyTestCase and GMock, while each of them may be quite capable of creating such a test I found the documentation for such an example lacking in all cases.
class Searcher {
def http = new HTTPBuilder('http://ajax.googleapis.com')
def _executeSearch = { searchQ -> {
req ->
uri.path = '/ajax/services/search/web'
uri.query = searchQ
requestContentType = URLENC
response.success = { resp, reader ->
assert resp.statusLine.statusCode == 200
reader.text
}
response.failure = { resp -> println "FAILURE! ${resp.properties}"
resp.statusLine.statusCode }
}
}
def executeSearch(query) {
// http.setHeaders(Accept: 'application/json') // I want JSON back, but this not important
http.request(GET, _executeGetCommand(query))
}
}
What I want/need to do is to mock 'http' in such a way that I can test:
1. uri.query is getting properly set via the passed in data
2. calls to response.success return mocked test data
3. calls to failure get executed and return the failure code
I am probably approaching this entirely incorrectly and will be open to the "right way" of going about unit testing such code. Please bear with me though as this is new to me!
I would use Spock mock's for your test case. They should be quite straightforward, since you don't need any actual network interaction during unit testing.
Spock mocks are documented pretty well in
the new spock docs
If you do want to test web services from the client side, check out geb, which works well as a companion to spock. Geb is documented in the Book of Geb Integration testing over the web obviously involves more moving parts, so you're right to start by mocking out the server side.

Unit test for web service (Service Reference) - xml deserialization

In Summary
I need a way to deserialize an XML string into an object normally returned by a 3rd party webservice.
Using C#.
In Detail
I have code that consumes a 3rd party Service Reference (Web Service) - so the usual stuff: we pass in a Request object and it returns a Response object.
Regarding unit testing - I'm not interested in the inner workings of the Service Reference since this is a 3rd party service. I'm only interested in two things:
Does my code generate the correct Request object?
When the Service Reference returns it's response, do I process this response correctly?
Taking each in turn:
Does my code generate the correct Request object?
This I can do. If anyone's interested in this, what I do is to replace my service reference with a RhinoMocks Mock object. In my unit test I call the method on my Mock and then check the arguments passed in, comparing the actual Request object against the expected Request object.
When the Service Reference returns it's response, do I process this response correctly?
What I want to do here is to create a RhinoMocks Stub of my service reference, so that when it's called this stub returns a response object populated with my test data.
The problem that I face is that the response objects returned by this particular 3rd party service are extremely complex. If I were to attempt to create one by hard-coding all the property values by hand then this would probably take me the best part of a whole day.
However, what I can very easily do is to capture the XML serialized response from this service. I could then easily edit it's values and store this XML in one of my unit tests.
What I'm after is an easy way to then "deserialize" this "test" XML into a response object and use this to program the response from my Stub.
Any help would be much appreciated.
Thanks
Griff
Turns out that this is quite simple:
public static object Deserialize(string xml, Type toType)
{
using(Stream stream = new MemoryStream())
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0, data.Length);
stream.Position = 0;
var s = new XmlSerializer(toType, "http://^your url^");
return s.Deserialize(stream);
}
}
Note that if you're using XML from a SOAP request, strip the SOAP envelop off first.
Griff

Strategies to mock a webservice

I'm implementing a client consuming a webservice. I want to reduce dependencies and decided to mock the webservice.
I use mockito, it has the advantage vs. EasyMock to be able to mock classes, not just interfaces. But that's not the point.
In my test, I've got this code:
// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);
// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLon()));
// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
.getInstance();
LocationBean locationBean = geoLocationFetcher
.extractGeoLocationFromXml(mDocument);
// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();
assertEquals(A_LOCATION_BEAN, locationBean);
What my code shows is that I "micro-test" the consuming object. It's like I would implement my productive code in my test. An example for the result xml is London on GeoNames.
In my opinion, it's far too granular.
But how can I mock a webservice without giving everystep? Should I let the mock object just return a XML file?
It's not about the code, but the approach.
I'm using JUnit 4.x and Mockito 1.7
I think the real problem here is that you have a singleton that calls and creates the web service so it is difficult to insert a mock one.
You may have to add (possibly package level) access to the singleton class. For example if the constructor looks something like
private GeoLocationFactory(WebService service) {
...
}
you can make the constructor package level and just create one with a mocked web service.
Alternatively you can set the webservice by adding a setter method, although I don't like mutable Singletons. Also in that case you have to remember to unset the webservice afterwards.
If the webservice is created in a method you might have to make the GeoLocationFactory extensible to substitute the mock service.
You may also look into remove the singleton itself. There are articles online and probably here on how to do that.
you really want to be mocking the results returned from the webservice to the code that will be using the result. In your example code above you seem to be mocking mDocument but you really want to pass in an instance of mDocument that has been returned from a mocked instance of your webservice and assert that the locationBean returned from the geoLocationFetcher matches the value of A_LOCATION_BEAN.
The easiest option would be to mock the WebService client,
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
You can modify the code to read the response xml from the file system.
Sample code can be found here: Mocking .NET WebServices with Mockito