У меня есть класс, который рефакторинг в 1 основной класс и 2 меньших класса. Основные классы используют базу данных (как это делают многие мои классы) и отправляют электронные письма. Таким образом, у основного класса есть IPersonRepository
и IEmailRepository
инъекция, которая, в свою очередь, отправляет 2 меньшим классам.
Теперь я хочу провести юнит-тестирование основного класса и научился не тестировать юниты внутренней работы класса, потому что мы должны иметь возможность изменять внутреннюю работу, не прерывая юнит-тесты.
Но , как класс использует IPersonRepository
и IEmailRepository
я ИМЕЮ указать (макет / манекен) результаты для некоторых методов для IPersonRepository
. Основной класс вычисляет некоторые данные на основе существующих данных и возвращает их. Если я хочу проверить это, я не вижу, как я могу написать тест, не указав, что IPersonRepository.GetSavingsByCustomerId
возвращает x. Но тогда мой модульный тест «знает» о внутренней работе, потому что он «знает», какие методы издеваться, а какие нет.
Как я могу протестировать класс с внедренными зависимостями, не зная теста о внутренностях?
фон:
По моему опыту, многие подобные тесты создают mock для репозиториев, а затем либо предоставляют правильные данные для mocks, либо проверяют, был ли вызван определенный метод во время выполнения. В любом случае, тест знает о внутренностях.
Теперь я видел презентацию о теории (которую я слышал ранее), что тест не должен знать о реализации. Во-первых, потому что вы не тестируете, как это работает, но и потому, что когда вы сейчас меняете реализацию, все модульные тесты не проходят, потому что они «знают» о реализации. Хотя мне нравится, что тесты не знают о реализации, я не знаю, как это сделать.
IPersonRepository
объект, этот интерфейс и все методы, которые он описывает, больше не являются «внутренними», так что это на самом деле не является проблемой теста. Ваш реальный вопрос должен заключаться в том, «как я могу реорганизовать классы в более мелкие единицы, не выставляя слишком много публике». Ответ таков: «Держите эти интерфейсы в тонусе» (например, придерживаясь принципа сегрегации интерфейса). Это ИМХО пункт 2 в ответе @ DavidArno (думаю, мне не нужно повторять это в другом ответе).