Моя первая работа по программированию познакомила меня с модульным тестированием и концепцией фиктивных объектов, но что-то в этом всегда было не так.
Допустим, мы писали банковское приложение, и нам нужно было смоделировать объект BankAccount:
// 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
}
У каждого класса есть цель:
- Существуют фабричные и фабричные интерфейсы, чтобы связать конструкторы с нашими фиктивными и реальными объектами.
- Статический класс BankAccountFactory позволяет нам
BankAccountFactory.Instance
назначить экземпляр IRealBankAccountFactory или MockBankAccountFactory в начале нашего производственного приложения или тестов соответственно.
- Как только все настроено правильно, любой класс может получить экземпляр IBankAccount, просто вызвав:
BankAccountFactory.Instance.getAccount(accountNum);
Это работает, но в результате получается много стандартного кода. Мне не нужно было писать 5 новых классов для каждого класса, который я хочу издеваться. Я убежден, что есть более простой способ, поэтому я должен спросить SO-сообщество:
Есть ли лучший или предпочтительный способ написания фиктивных объектов?
[Изменить, чтобы добавить:] Я ценю ссылки на макеты и DI-фреймворки, но сейчас я работаю над приложением 500 KLOC, и по крайней мере 60% кода состоит из Образцовые макеты в стиле выше.
Я просто хочу уменьшить размер кодовой базы без переписывания больших кусков кода для Yet-Another-Framework ™, так что это помогает мне больше видеть ложные классы, написанные от руки. :)