Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do I test this?

29 views
Skip to first unread message

Michael Simpson

unread,
Mar 1, 2002, 2:11:02 PM3/1/02
to
Hi all,
I have an existing application that I need to extend. While doing so,
I also want to introduce a bit of XP by getting a good suite of unit
tests for the new (and some of the existing) code. However, I've run
into a wall because I'm not sure how to go about it.

The applications is written in Visual C++ and exposes a COM object.
Clients pass requests to the COM server and then wait for an event to
be called signalling the response.

The COM server receives the request from the client and adds it to a
queue. Another thread monitors the queue, reads the request, calls a
sub-classed formatting object to format it for it's recipient, and
then uses sockets over a dial-up PPP connection to send the request
and receive the response. When the response is received, the
formatting object decodes it back into the internal application format
and fires the response event to the initial client. The code I'm
writing is another sub-classed formatting object for a new recipient
so most of what I'm doing is formatting the request and then decoding
the response.

My question is how do I test this beast? If it was Java, I wouldn't
be having this much trouble, but since it's asynchronous Windows C++
ATL COM... I created a testing project that can instantiate the COM
server, make a request, and then catch the response event. But I want
to get a lot lower than that. I want to be able to check the
formatting with both good and bad inputs without having to be
connected over the dial-up. I want to be able to test my decoding
routines for all possible results. But with the code-under-test being
COM, I don't think I can even create an instance of my object
externally so I can directly call the methods to test them. I would
rather not add test code to the actual project. I refuse to believe
that this code is untestable, but it's definitely got me stumped.

Any suggestions are more than welcome.

Thanks,
Mike

Tokomar

unread,
Mar 1, 2002, 2:27:14 PM3/1/02
to
Michael Simpson wrote:

> My question is how do I test this beast? If it was Java, I wouldn't
> be having this much trouble, but since it's asynchronous Windows C++
> ATL COM... I created a testing project that can instantiate the COM
> server, make a request, and then catch the response event. But I want
> to get a lot lower than that. I want to be able to check the
> formatting with both good and bad inputs without having to be
> connected over the dial-up. I want to be able to test my decoding
> routines for all possible results. But with the code-under-test being
> COM, I don't think I can even create an instance of my object
> externally so I can directly call the methods to test them. I would
> rather not add test code to the actual project. I refuse to believe
> that this code is untestable, but it's definitely got me stumped.

You are wise not to try to test COM; that is Microsoft's burden.

But inside every fat object is a thin one trying to come out.

Put all the custom implementation that COM calls into a single C++ class.
Test that.

Then let the COM object own (by value) a single instance of this class, and
delegate every method call into it. Because these delegations are simple
(though redundant), and because MS tests COM for you, your tests that drive
the entire COM object are less important.

Finally, there are usually ways to call a DCOM object without using a
network connecton.

--
Tokomar

Jeff Grigg

unread,
Mar 2, 2002, 12:13:52 PM3/2/02
to
Answer: MockObject

See: http://www.c2.com/cgi/wiki?MockObject

This is how to apply MockObject in your case:
To test your formatting class/object indepedently of all other classes
(except parent class(es) it inherits from), then your class and all
its parents must interact with the outside world through interfaces --
not direct references to concrete classes. I assume that the parent
class you inherit from "uses sockets over a dial-up PPP connection to
send the request and receive the response" and "fires the response
event to the initial client." You must change the parent class to do
these things through an interface (a class with nothing but pure
virtual functions). I usually do it this way: (#1) Make the parent
class constructor create an instance of the normal "external world"
concrete object and hold it in an instance variable. (#2) Provide a
DEBUG-version-only public 'property set' method to override this
instance variable with a MockObject that implements the same
interface. Then (#3) you can test your formatting class without
sockets or firing responses to a client.

Here's an alternate way to do it:
Do conditional compilation so that in a *DEBUG-TESTING* build your
formatting class inherits from a "MockParent" class that provides the
same services as the class you normally inherit from, but which acts
like a MockObject. (It's a bit trickier, but is more likely to avoid
the political backlash of messing up "everyone else's" code. ;-)

_ _ _


Take heart! This approach can work!

I have just spent several weeks testing IIS MTS Site Server objects.
I do 99% of my testing without touching the web server box *at all*.
(This, in spite of the fact that several of the web server components
*CRASH* the process whenever I even create their instances on my
development/unit-testing box.)

MockObject is the answer: I have an ExternalInterface class/interface
containing all references to Request and Response objects, and other
web server components. During UnitTesting, I replace
ExternalInterface with an instance of 'MockExternalInterface' -- a
class I can completely control. The ExternalInterface class is so
simple it doesn't need testing. (The fact that the system works at
all "proves" that it's correct. ;-) And the 'MockExternalInterface'
class is *blindingly* simple: Everything is hard coded or controlled
by public properties. I can make it simulate all kinds of "nearly
impossible" web server conditions. (...like what happens when the IIS
Request object fails to implement the COM GUID interface *they define*
in their own type library! ;-)
- jeff

0 new messages