My first programming job introduced me to unit testing and the concept of mock objects, but something always felt wrong about it.
Let’s say we were writing a bank app, and needed to mock a BankAccount object:
// boilerplate code public interface IBankAccount { void Deposit(int amount); void Withdrawal(int amount); int getBalance(); int getAccountNumber(); } public interface IBankAccountFactory { IBankAccount getAccount(int accountNumber); } public class ProductionBankAccountFactory implements IBankAccountFactory { public IBankAccount getAccount(int accountNumber) { return new RealBankAccount(accountNumber); } } public class MockBankAccountFactory implements IBankAccountFactory { public IBankAccount getAccount(int accountNumber) { return new MockBankAccount(accountNumber); } } public static class BankAccountFactory { // ewww, singletons! public static IBankAccountFactory Instance; } // finally, my actual business objects public class MockBankAccount implements IBankAccount { public MockBankAccount(int accountNumber) { ... } // interface implementation } public class RealBankAccount implements IBankAccount { public RealBankAccount(int accountNumber) { ... } // interface implementation }
Each class has a purpose:
- The factory and factory interfaces exist to wrap up the constructors to our mock and real objects.
- The static BankAccountFactory class allows us to assign
BankAccountFactory.Instancean instance of IRealBankAccountFactory or MockBankAccountFactory at the start of our production app or tests respectively. - Once everything is set up properly, any class can grab an instance of IBankAccount simply by calling:
BankAccountFactory.Instance.getAccount(accountNum);
This works, but it results in a lot of boilerplate code. I shouldn’t have to write 5 new classes for each class I want to mock. I’m convinced there’s an easier way, so I have to ask the SO community:
Is there a better or preferred way of writing mock objects?
[Edit to add:] I appreciate the links to the mocking and DI frameworks, but right now I’m working on a 500 KLOC application, and at least 60% of the code consists of the boilerplate mock classes in the style above.
I just want to reduce the size of the codebase without re-writing large chunks of code for Yet-Another-Framework™, so it helps me more to see mock classes written by hand. 🙂
The better way is to have someone else write it. Some options here are:
Moq – http://code.google.com/p/moq/
Rhino Mocks – http://ayende.com/projects/rhino-mocks.aspx