Вы пытаетесь сделать две вещи одновременно:
- протестируйте различные реализации вашего кода и
- проверка того, что правильная реализация выбрана в зависимости от обстоятельств (или, в более общем смысле, от того, что ваше приложение работает независимо от того, присутствует ли данная библиотека)
Разделение двух задач на отдельные тесты упрощает проблему. Таким образом, я реализовал бы две версии вашего кода как две стратегии и поместил код, который проверяет путь к классу и создает необходимую стратегию в Factory (метод). Тогда обе стратегии могут быть проверены модулем независимо от настроек загрузчика классов и пути к классам:
interface MyStrategy {
public void doStuff();
}
class MyLibraryUsingStrategy implements MyStrategy {
public void doStuff() {
// call the library
}
}
class MyEmbeddedStrategy implements MyStrategy {
public void doStuff() {
// embedded code
}
}
В модульных тестах вы можете просто создать и протестировать любую из конкретных стратегий:
@Test
void testEmbeddedStrategy() {
MyStrategy strategy = new MyEmbeddedStrategy();
strategy.doStuff();
// assert results
}
Простой фабричный метод для создания соответствующей стратегии:
MyStrategy createMyStrategy() {
MyStrategy strategy;
try {
Class.forName("net.sf.ehcache.CacheManager");
strategy = new MyLibraryUsingStrategy();
} catch (ClassNotFoundException e) {
strategy = new MyEmbeddedStrategy();
}
return strategy;
}
Поскольку заводской код довольно тривиален, вы можете даже не писать автоматические тесты для него. Но, во всяком случае, тестирование фабрики - это больше (часть) интеграционного теста, чем модульное тестирование; вы можете просто собрать различные настройки вашего приложения - одну с другой, а не с соответствующей библиотекой - и убедиться, что обе они работают правильно.