Пустой виртуальный метод вместо интерфейса
Вот только есть ещё одна загвоздка - юнит у нас не класс. Юнит у нас - метод.
Да хоть кого выбери юнитом. Юнит в любом случае должен работать с абстракциями.
Ну и как же мне сделать этот код тестируемым по феншую?
Очень просто - использовать абстракции. Если их нет, то ввести :) Использовать "тонкие" DTO,
Можно также использовать прокси-объекты.
Было бы желание сделать по феншую :)
Ну, т.е. расширить продуктивный код исключительно в интересах юнит теста, сделает его менее читаемым и добавить возможность подклассу поломать ПК, переписав мой метод.
Ну это зависит от того, как расширять :) Совсем необязательно, что будет менее читаемым.
А может лучше воспользоваться рефлексией и подставить в приватное поле other.primaryKey (унаследованное от суперкласса Entity) значение 123?
Угу, а еще тебе понадобится реальная БД, т.к. где-нибудь в этом Entity погребено подключение к БД. Надо будет держать эту БД в валидном для теста состоянии. А еще не дай бог кому-то придет в голову поменять логику Entity и приватное в лучшем случае удалят, а в худшем - будут использовать как-то иначе. Или натрафят обфускатор :)
А бывают DI фреймворки, которые ТРЕБУЮТ чтобы конструктор был пустым.
Ну во времена, когда один класс может имень много конструкторов это вообще самая маленькая проблема в мире :)
И именно потому что экосистема к коду архитектурное требование - сеттеров быть не должно (мнэ, на вашем языке - проперть ридонли :)) Потому что значения установит DI. А геттеры или финальные (не переписываемые) или их нет, чтобы не давать доступа к полю даже наследникам.
Да пофиг :) Переходи на уровень абстракций, т.е. интерфейсов. На этом уровне совершенно наплевать на всякие там финальные или приватные методы/проперти... их просто нет, т.к. интерфейс по определению публичный :)
И угадай с трёх раз, что же обычно выбирают?
Стреляющие себе в ногу выбирают рефлекшены :) Это ж очевидно :D :D :D