有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为不太可能的场景创建单元测试,值得这么麻烦吗?

对于下面的方法,有没有办法创建单元测试来引起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;
}

共 (2) 个答案

  1. # 1 楼答案

    这里检查的异常由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;
        }
    }
    

    所以当ServiceConfigurationError被抛出并捕获时DatatypeConfigurationException被抛出。但是ServiceConfigurationError是一个错误,而不是一个例外
    试图模拟一个错误会变得非常困难

    2)测试它的其他替代方法:在自己类的实例中包装DatatypeFactory.newInstance()
    通过这种方式,你可以毫不费力地模仿它:

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

    现在用以下方式更改代码:

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

    现在,您可以在测试类中模拟dataTypeFactoryWrapper

    3)最后一种选择:不要测试它。考虑它是,即^ {< CD7> }包装器和^ {CD7}}是难/棘手的。br/> 无论javadoc如何解释:

    An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions

  2. # 2 楼答案

    你可以:

    1. 例如,使用PowerMock模拟静态方法(DatatypeFactory.newInstance()),并将其设置为引发DatatypeConfigurationException。然后在单元测试中检查这个异常是否由ConversionException包装

    2. 因为我不太喜欢模仿静态方法——我会创建新组件——比如XmlGregorianCalendarProvider(它将使用DatatypeFactory.newInstance()。使用标准模拟机制(例如JUnit)对其进行模拟。 然后在单元测试中检查这个异常是否由ConversionException包装