Why you're missing the point if you use a framework to generate mock objects for you...

Roy Osherove links to Mockpp a mock object framework for C++ and comments on how the framework is painful to use (and it looks like it was painful to write…) He concludes that he’s getting on just fine writing his mocks manually… In my experience you’d miss a lot of very useful learning and design work if you didn’t write the mocks manually…

If you’re using a mock object to help you test a piece of code that’s under development, that is, you’re doing TDD or something close, then the act of creating the mock is useful for the design work that you’re doing by doing TDD… Using a framework to create your mocks for you means that you don’t get to experience as much of the “being a client of your own code” experience as you might otherwise, therefore it’s something to avoid; IMHO…

TDD is all about the design. By writing a test before you write production code you think about the interface that clients of the production code will need to use. You’re working as a client programmer and the tests will drive the design towards something that’s nice to use from a client perspective. This is a Good Thing. In fact it’s The Point!

When you write a mock object you’re interacting with your production code in the way that a client would have to. Say your component takes an object that implements X, well, by writing a mockX you get to experience the pleasure (and pain) that a client would experience. If the component under test is buried deep inside your API then that client is YOU anyway… Writing the mock object is good for you (like eating your greens). If the mock is too hard to write then perhaps the interface you’re mocking up could be better… If you just flick a switch and have some framework generate you a mock then you’ll never know and you’ll miss out on a valuable learning experience.

So, in summary, don’t be a lazy arse, write your own mocks :)

I tend to use a simple test log class that just accepts strings and can later be tested to see what it contains and then construct my mocks something like this;

void CMockIOPool::Dispatch(
   IHandler &handler, 
   OVERLAPPED *pOverlapped,
   const DWORD numBytes) const
{
   LogMessage(_T("Dispatch")); // + ToString(&handler) + _T(":") + ToString(pOverlapped) + _T(":") + ToString(numBytes));
 
   handler.HandleOperation(static_cast<IBuffer*>(pOverlapped), numBytes, 0);
}
 
void CMockIOPool::AssociateDevice(
   HANDLE hDevice, 
   IHandler &handler) const
{
   LogMessage(_T("AssociateDevice"));// + ToString(hDevice) + _T(":") + ToString(&handler));
 
   m_iocp.AssociateDevice(hDevice, reinterpret_cast<ULONG_PTR>(&handler));
}

and this works pretty well for me…

Programming should be as simple as possible but not simpler. Sometimes I despair that people insist on going that extra mile to avoid a task and in doing so avoid the learning that comes from actually doing the task.