Создайте юнит-тест для маловероятного сценария, и стоит ли это того? - PullRequest
0 голосов
/ 11 января 2019

Для метода ниже, есть ли способ создать модульный тест, чтобы вызвать DatatypeConfigurationException, поэтому я могу проверить, что он бросил ConversionException?

Вот мой код:

public static XMLGregorianCalendar getXMLGregorianCalendar(final LocalDate localDate) {
    XMLGregorianCalendar xmlGregorianCalendar = null;
    if (localDate != null) {
        final String dateString = localDate.format(yyyMMddFormat);
        try {
            xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateString);
        } catch (DatatypeConfigurationException e) {
            throw new ConversionException("Unable to format LocalDate.", e);
        }
    }

    return xmlGregorianCalendar;
}

Ответы [ 3 ]

0 голосов
/ 11 января 2019

Вы можете либо:

  1. Имитировать статический метод (DatatypeFactory.newInstance ()), используя, например, PowerMock, и настроить его для выброса исключения DatatypeConfigurationException. Затем в модульном тесте проверьте, что это исключение заключено в ConversionException.

  2. Поскольку я не большой поклонник насмешливых статических методов - я бы создал новый компонент - скажем, XmlGregorianCalendarProvider (который будет использовать DatatypeFactory.newInstance (). NewXMLGregorianCalendar (dateString) для внутреннего использования) и вместо этого смоделировал бы его, используя стандартный макет механизм (например, JUnit). Еще тогда в модульном тесте проверь, что это исключение обернуто в ConversionException.

0 голосов
/ 11 января 2019

Здесь проверенное исключение выдается javax.xml.datatype.DatatypeFactory.newInstance().
Это статический метод. Таким образом, вы не можете издеваться прямо.

1) В качестве альтернативы вы можете попытаться найти сценарий, который может спровоцировать возникновение исключения.
Поехали. Исключение составляет здесь:

private static <T> T findServiceProvider(final Class<T> type)
        throws DatatypeConfigurationException{
    try {
        return AccessController.doPrivileged(new PrivilegedAction<T>() {
            public T run() {
                final ServiceLoader<T> serviceLoader = ServiceLoader.load(type);
                final Iterator<T> iterator = serviceLoader.iterator();
                if (iterator.hasNext()) {
                    return iterator.next();
                } else {
                    return null;
                }
            }
        });
    } catch(ServiceConfigurationError e) {
        final DatatypeConfigurationException error =
                new DatatypeConfigurationException(
                    "Provider for " + type + " cannot be found", e);
        throw error;
    }
}

Таким образом, DatatypeConfigurationException выбрасывается, когда ServiceConfigurationError брошен и пойман. Но ServiceConfigurationError - это ошибка, а не исключение.
Попытка смоделировать ошибку становится очень хакерской.

2) Другая альтернатива для проверки: обернуть DatatypeFactory.newInstance() в экземпляр вашего собственного класса.
Таким образом, вы можете без труда издеваться над ним:

public class DataTypeFactoryWrapper { 
   public DatatypeFactory newInstance(){
      return DatatypeFactory.newInstance();
   }
}

Теперь измените ваш код следующим образом:

private DataTypeFactoryWrapper dataTypeFactoryWrapper;

//...
xmlGregorianCalendar = dataTypeFactoryWrapper.newInstance().newXMLGregorianCalendar(dateString);

Теперь вы можете высмеивать dataTypeFactoryWrapper в вашем тестовом классе.

3) Последний вариант: не проверяйте его. Считайте, что это так, это оболочка Error и Error сложно / сложно проверить.
Что бы ни объяснял Javadoc:

Ошибка - это подкласс Throwable, который указывает на серьезные проблемы что разумное приложение не должно пытаться поймать. Большинство таких ошибки ненормальные условия

0 голосов
/ 11 января 2019

Вы можете переопределить реализацию, которую создаст фабрика, установив системное свойство с именем класса для создания экземпляра. Затем этот класс может вызвать исключение в этом методе.

Например, вот так

public class FailingDatatypeFactory implements DatatypeFactory {
   public XMLGregorianCalendar newXMLGregorianCalendar() { throw new DatatypeConfigurationException() }
}

и затем настройте его так

System.setProperty("javax.xml.datatype.DatatypeFactory", FailingDatatypeFactory.class.getName());

Теперь после запуска тестового примера вы должны очистить свойство, чтобы никакие другие тесты не пытались создать экземпляр этой реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...