Моя первая работа по программированию познакомила меня с модульным тестированием и концепцией фиктивных объектов, но что-то в этом всегда было не так.
Допустим, мы пишем банковское приложение, и нам нужно смоделировать объект 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™, поэтому мне больше помогает увидеть фиктивные классы, написанные вручную. :)