Если вам абсолютно необходимо достичь 100% покрытия кода - достоинства этого можно обсудить в другом месте :) - вы можете добиться этого, используя отражение в своих тестах. По привычке, когда я реализую класс статических утилит, я добавляю приватный конструктор, чтобы гарантировать, что экземпляры класса не могут быть созданы. Например:
/**
* Constructs a new MyUtilities.
* @throws InstantiationException
*/
private MyUtilities() throws InstantiationException
{
throw new InstantiationException("Instances of this type are forbidden.");
}
Тогда ваш тест может выглядеть примерно так:
@Test
public void Test_Constructor_Throws_Exception() throws IllegalAccessException, InstantiationException {
final Class<?> cls = MyUtilties.class;
final Constructor<?> c = cls.getDeclaredConstructors()[0];
c.setAccessible(true);
Throwable targetException = null;
try {
c.newInstance((Object[])null);
} catch (InvocationTargetException ite) {
targetException = ite.getTargetException();
}
assertNotNull(targetException);
assertEquals(targetException.getClass(), InstantiationException.class);
}
По сути, здесь вы получаете класс по имени, находите конструкторы для этого типа класса, устанавливаете его в public (вызов setAccessible
), вызываете конструктор без аргументов и затем гарантируете, что выбрасывается целевое исключение InstantiationException
.
В любом случае, как вы сказали, требование 100% покрытия кода здесь является болезненным, но, похоже, это не в ваших руках, поэтому вы мало что можете с этим поделать. Я на самом деле использовал подходы, подобные вышеупомянутым, в своем собственном коде, и я нашел это полезным, но не с точки зрения тестирования. Скорее, это просто помогло мне узнать немного больше об отражении, чем я знал раньше :)