Точно, юнит тесты )
Фух, ну перед тем, как написать тест наверно нужно предоставить тестируемому функционалу всё, что ему необходимо для работы, т.е. мокнуть данные и т.д.
Далее уже описать необходимое поведение функционала
То есть, мы мокаем с ним как с черным ящиком, мокаем все входы и выходы, а затем смотрим, что просходит. Параллельно стараемся документировать код тестами, чтобы другой разработчик знал как его можно использовать.
А что делать, если тест получается сложным?