The Joel on Software Discussion Group (CLOSED)

A place to discuss Joel on Software. Now closed.

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

An idea for testing tightly coupled code

I'm trying to figure out how I can test some very tightly coupled code that we are working on.  Please let me know if anyone has done this before or if I'm totally out of it today.

So, for objects that need to talk with one another, instead of having one object maintain a pointer or reference to another object, perhaps all of the objects might have a pointer or reference to a single message broker object.  When one object wants to talk to another object, it simply sends a message to this message broker and the message broker delivers the message to the proper object, and returns the correct value (if there is one) to the callee.  I guess this is similar to something like RPC but all within one process.

Some sort of scheme needs to be figured out by which objects identify each other as well as some scheme that deals with passing parameters and getting return values.

Using this approach in order to test what was once a tightly coupled piece of software, for each object you'd just need to write the test code inside of the message broker, and the object being tested would never know the difference.
testing nightmare
Wednesday, June 25, 2008
 
 
Having all objects send messages via a broker could slow things down a lot by causing mutex deadlocks, etc. (obviously depending on how many messages are sent)

Maybe better to have an object which puts other objects in contact with each other but once connected the objects communicate directly.
Jimmy Jones
Wednesday, June 25, 2008
 
 
This pattern comes up a lot...

My current project involves a lot of SOAP messaging and the company I'm at, (large fortune-5 place) uses IBM's DataPower appliance.  DataPower is becoming the company's messaging HUB.  In this environment, DataPower is well suited -- it's fast due to hardware acceleration.

In my company's accounting/erp software we distribute modules that have a dependency tree.  And modules can "talk" to other modules.  In this space we have our own application stack where we push parameters onto a stack and function calls and then look to pop the stack for return values.  We create interface specifications for each module that describe the expectations, etc... This has worked so well that we wound up developing framework upon which we base new software on this model and code.  It makes testing very easy too.. The testing, built on same framework, can invoke modules in a very consistent way and we hardly ever modify the testing code itself.

My point is that "tightly coupled code" can have different incarnations.  For SOAP messaging we use SOAPUI and for the stack example, we rolled our own.

I realize there are all sorts of testing suites out there but... But my experience tells me that testing is can't be to generically defined but patterns do exist in that functions can be decoupled.  The big deciding factor appears to be the implementation which can vary!

my 2 cents.
~Eric
Wednesday, June 25, 2008
 
 
"In this space we have our own application stack where we push parameters onto a stack and function calls and then look to pop the stack for return values.  We create interface specifications for each module that describe the expectations, etc..."

This is pretty interesting.  It seems very similar (identical perhaps) to the way compilers implement function calls in assembly code.  (Very often, compilers will use registers to pass parameters, but they also use the stack as well - if my Compilers class recall is strong today).  Does this occur between objects in the same process?  Or between separate processes?  Is there a name for this kind of inter-object/process communication?
testing nightmare
Wednesday, June 25, 2008
 
 
step-in
lemon shakespear obrien Send private email
Wednesday, June 25, 2008
 
 
You would create a development nightmare, if you did what you suggest.  I'll presume you're coding in C++.

Have object maintain (possibly as boost::shared_ptr) references to interfaces.  When you want to test an object, replace all of its references to the outside world with mock objects that implement those interfaces, but provide fake data.

If you insist on decoupling it more like you suggest, then don't use a single message-passing object.  That's nuts.  Implement each object as a collection of boost::function objects.  The object just calls the boost::function, not knowing what you've bound it to (using boost::bind).

If you want to move in a direction like you're talking about, then go with Observer / Notifier pattern - which does not require a central messaging object.

And for the love of god, if you're making a central messaging object, then don't allow people to queue up messages, and process them later.  You will never be able to undo the mess that causes in your code.

I highly recommend "Working Effectively With Legacy Code" by Michael Feathers.
Because My Company Has What You Suggested And It Sucks Ass
Wednesday, June 25, 2008
 
 
"Does this occur between objects in the same process?"

Yes, in some instances it does where it makes sense.  For example, we sometimes have a screen that will make a call to a lookup module same lookup module used by all other modules and by passing a name, that name references all sorts of details about how the lookup functions.  That name is a key in a database.

The calling module will in this case want the return value to populate some fields.  So in the field population we could either perform another call or simply exercise the RTT of the control (i.e. look it up and populate it's display/text attribute); so yes C++ here.



"Or between separate processes?  Is there a name for this kind of inter-object/process communication?""

No, not between processes such as separate running instances but we could - nothing stopping us.  Not enough room here to really get into our implementation but that's my point.  My opinion is that the implementation details are what complicate the matter to begin with.

"If you insist on decoupling it more like you suggest, then don't use a single message-passing object.  That's nuts."

No it's not nuts!  This is precisely how you integrate web application.  In Java, for example, you can use message queues to handle synchronous as well as asynchronous communication queues.

"And for the love of god, if you're making a central messaging object, then don't allow people to queue up messages, and process them later.  You will never be able to undo the mess that causes in your code."

Generally speaking that's not a problem for folks who know what they are doing which is why you typically will use a proven library for this.  Also I've seen many implementations of this in C++, Java, .NET, and even in Perl -- XML serialization/deserialization comes to mind because it falls into this category when crossing domain boundaries such as in SSO (Single Sign On) and SOAP messaging situations.
~Eric
Thursday, June 26, 2008
 
 
Eric,

If you have a need for processing messages from the outside world, go for it.

But to purposely inject a *single instance* of a messaging class between all of your objects is, in a word, nuts.

You may have legitimate reasons to have a message queue in front of a few different objects, such as on threads.  But to have a single message queue which will accept any message and pass it on to any receiver, is a huge architectural nightmare.

I don't get what XML Serialization / Deserialization has to do with passing messages between objects.  Sure, you could use them to package up the message, but that's the only reason I see to inject them into the conversation.
Because My Company Has What You Suggested And It Sucks Ass
Friday, June 27, 2008
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz