views:

58

answers:

4

I have a Java 6 based web service client using the standard Java 6 annotation based approach (i.e. no Axis or other third party web service library), which works very well. So does the web service I am calling, which is nice, but now I need to write error handling code, and I need to be able to make the existing web service unreliable in a controlled way.

There are many mock frameworks, and they may be helpful, but I don't need right now to be able to mock out the service with prerecorded answers or anything, just introduce unreliability causing the web service library to fail so I can handle the situation gracefully. This would probably be a proxy server running locally.

I work with Eclipse JEE 3.6, but Netbeans, IntelliJ and JDeveloper are also options.

What would be the best way to do this?

A: 

Any introduced instability is likely to lead to operation avenues of instability being missed. Aim to cover all potential error vectors in your code rather than trying to mitigate for specifics.

Lazarus
I primarily need to handle the "sorry, not here" and "yes, we are here but we time out" situations. Also please notice I have no control over the web service server.
Thorbjørn Ravn Andersen
What about the "here's some incorrectly formatted data", "who are you?", etc. You're going to be using a try/catch block for this so catch the specific exceptions you are looking for but be prepared for your app to bomb with the rest.
Lazarus
Bombing for unexpected situations is fine. Do you have a suggestion for what I could use for my stated needs?
Thorbjørn Ravn Andersen
If you know the error conditions you want to trap then do so in a try/catch block and catch the exceptions you want. Given that any simulated failure is likely to be unreliable (as it's based on a multitude of assumptions) you should be fine without trying to test it.
Lazarus
I know the error conditions but I do not know how the web service library will react to those conditions, hence I need to provoke them.
Thorbjørn Ravn Andersen
You are missing my point, if you artificially provoke the error conditions that you are looking to capture there is no assurance that your artificial method will actually mirror production errors. Whatever eventualities you *think* you have covered, there will be an unexpected condition for your first production issue, hence my indication that you should code for *all* errors and trust your catch-all.
Lazarus
A: 

Since You've not disclosed enough details of your setup, maybe throwing Exception here and there would be enough?

Seriously, for integration tests like this I'd suggest running some subset of a real web service container.

Based on service's logic it may behave unreliably because of:

  • external system it is using is misbehaving - try to mock the external system and throw faults - different types - from it
  • database access problem - try mocking DAO layer and throw Exception from there
  • general hardware problem - depends :) try to stress your code as you see fit
Marcin Cylke
What do you need to know about my setup?
Thorbjørn Ravn Andersen
As I wrote in my answer, it would be nice to know the architecture of the WS - what it is supposed to do. I may overcomplicate this, but from my point of view your WS could do lots of things, each of which could result in failure condition. You could briefly describe the flow of logic in your WS.*Moreover* you wrote about "introduce unreliability", but of what sort? Because a simple error from WS you'll get with just an exception thrown from the service.If you want to simulate timeout, you should introduce some kind of delayer in the way of your test harness.
Marcin Cylke
It is not _my_ web service, it is a web service I _call_. Consider it - as we do - to be a simple, and idempotent lookup service behaving like a java.util.Map.
Thorbjørn Ravn Andersen
A: 

I think rather than introducing unreliability to a running-instance of the web service application, you are better off simulating error conditions in your unit/integration tests and asserting that your top-layer of the service responds the way that you would like.

For example:

  1. How does the service entry-point respond to a request if the data layer reports that it cannot communicate with the backend (if the data layer throws exceptions, or however it indicates failure)
  2. How does the service entry-point behave if other required components are throwing "unavailable"-like exceptions?
  3. Do you have any timeout logic in place, i.e. the service returns an error if it takes more than X seconds to process the request? If so, this can be simulated in a mock test as well.
matt b
I may have worded myself imprecisely. I need to provoke the web service library to react to certain error conditions to be able to handle its response to said conditions. For instance one exception found to be thrown after asking the question originally is `javax.xml.rpc.soap.SOAPFaultException` which extends RuntimeException directly.
Thorbjørn Ravn Andersen
+2  A: 

Tcpmon, http://ws.apache.org/commons/tcpmon/index.html can be set up to act as a proxy and even simulate slow connections. That would give you a chance to simulate both "sorry, not here" and "yes, we are here but we time out".

Kennet
Thanks for suggesting this. It looks useful!
Thorbjørn Ravn Andersen