В любом тесте есть две части: заставить его произойти и измерить, чтобы вы получили правильный результат.
Fault Injection
Самый простой ответ - тот, который уже был упомянут, - установить cacheFileName
в файл, который никогда не будет существовать. Это, вероятно, самый практичный ответ в этой ситуации.
Однако, чтобы вызвать произвольное условие, такое как IOException
, вам действительно нужно Fault Injection . Это вызывает ошибки в вашем коде, не вынуждая вас использовать ваш исходный код. Вот несколько способов сделать это:
- Макет объектов Вы можете использовать фабричный метод для создания переопределенных
ObjectOutputStream
или FileOutputStream
. В тестовом коде реализация выдаст IOException
, когда вы захотите, а в рабочем коде не изменит нормальное поведение.
- Внедрение зависимостей Для того, чтобы получить ваш ложный объект в нужном месте, вы можете использовать такие рамки, как Пружина или Шов , чтобы "ввести" соответствующий объект в классе, который делает работу. Вы можете видеть, что эти инфраструктуры даже имеют приоритет для объектов, которые будут внедрены, так что во время модульного тестирования вы можете переопределить производственные объекты тестовыми объектами.
- Аспектно-ориентированное программирование Вместо того, чтобы вообще изменять структуру вашего кода, вы можете использовать AOP для ввода ошибки в нужное место. Например, используя AspectJ , вы можете определить Pointcut , из которого вы хотите, чтобы было сгенерировано исключение, и Advice сгенерировать нужное исключение.
Есть другие ответы на внедрение ошибок в Java; например, продукт под названием AProbe впервые создал то, что можно было назвать AOP в C, и у них также есть продукт Java.
Проверка
Получение исключения - хорошее начало, но вы также должны подтвердить, что получили правильный результат. Предполагая, что пример кода у вас там правильный, вы хотите проверить, что вы зарегистрировали это исключение. Кто-то выше упомянул об использовании объекта Mock для вашего регистратора, что является приемлемым вариантом. Вы также можете использовать AOP здесь, чтобы перехватить вызов регистратору.
Я предполагаю, что логгер log4j ; Чтобы решить аналогичную проблему, я реализовал свой собственный app4 log4j, который захватывает выходные данные log4j: я специально собираю только ERROR
и FATAL
, которые, вероятно, будут интересными сообщениями журнала в таком случае. Ссылка на appender указана в log4j.xml
и активируется во время тестового прогона для записи выходных данных журнала ошибок. По сути, это фиктивный объект, но мне не пришлось реструктурировать весь мой код, получивший log4j Logger
.