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.Instance
an 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. :)