如何从JUnit中具有InputStream的方法覆盖IOException

问题描述

想在我的JUnit测试中寻求帮助。在我的方法中,我能够覆盖所有需要抛出IOException的部分。我对此做了很多变通方法,但似乎都没有。

这是单元测试中未涵盖IOException的方法

public String GetstrXMLValue(String strXML,String strCriteria) {
    SAXBuilder builder = new SAXBuilder();
    builder.setProperty(XMLConstants.ACCESS_S1,"");
    builder.setProperty(XMLConstants.ACCESS_S2,"");

    Document xmlDocument;
    String strValue = "";
    ErrorHandler objErrHdl = new ErrorHandler();
    
    try {
        InputStream objStream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));

        xmlDocument = builder.build(objStream);
            
        XPathFactory xpath = XPathFactory.instance(); 
      
        XPathExpression<Object> expr = xpath.compile(strCriteria);
      
        List<Object> xPathSearchednodes = expr.evaluate(xmlDocument);
        
        if (xPathSearchednodes.size() > 0) {
        
            Content content = (Content) xPathSearchednodes.get(0);
            
            strValue = content.getValue().toString();
        }
        
    } catch (JDOMException e) {
        objErrHdl.LogError(this.getClass().getName(),"GetstrXMLValue","ERROR RETRIEVING XML VALUES (XML=" + strXML + ";CRITERIA=" + strCriteria + ")",e.toString());
    } catch (IOException e) {
        objErrHdl.LogError(this.getClass().getName(),e.toString());
    } catch (Exception e) {
        objErrHdl.LogError(this.getClass().getName(),e.toString());
    }
            
    return strValue;
}

这是我的JUnit测试

@Test
public void testGetstrXMLValueThrowsIOException() throws IOException,ParserConfigurationException,SAXException,NoSuchMethodException,SecurityException,illegalaccessexception,IllegalArgumentException,InvocationTargetException,NoSuchFieldException {
    OutputStream responseBody = new ByteArrayOutputStream();
    String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
            "                <RESULT>\r\n" + 
            "                <SHORT_NAME>XXXXXXXXXXXXX</SHORT_NAME>\r\n" + 
            "                <ID_CODE>9999999999999</ID_CODE>\r\n" + 
            "                </RESULT>";
    
    xmlHandler.XMLGenerateRootResult();
    xmlHandler.GetstrXMLValue(xml,".//RESULT/ID_CODE/text()");
    try
    {
        InputStream input = XMLHandlerTest.readxml(xml);
        byte[] buffer = new byte[1024];
        int bytesRead;
        input.close();
        while ((bytesRead = input.read(buffer)) > 0)
        {
            responseBody.write(buffer,bytesRead);
            
            throw new IOException();
        }
    }
    catch(IOException e)
    {
        System.out.println(e);
    }

}

解决方法

您的问题不清楚。

您的意思是:如果发生IOException,如何使测试失败

通过不抓住它。如果测试用例抛出异常,则其默认行为是将测试用例视为失败。请注意,System.out.println(e);会抛出大量有关该错误的有用信息, AND 表示代码将继续运行。如果在catch块中进行操作,e.printStackTrace();LOG.something()System.out.println()基本上都是bug。别那样做。如果您不愿意处理问题或不知道如何处理,则catch块中唯一正确的“ I dunno”代码是:

catch (Whatever e) {
    throw new RuntimeException("uncaught",e);
}

在这种情况下,只需完全删除try / catch,如果发生IOException,测试将正确失败。

您的意思是:如果 IT 抛出IOException,我需要测试我的方法;我如何测试它是否正确?

好吧,没有意义,是吗?如果发生IOException,则您的方法显然被破坏了,因为您的方法将记录一些内容并继续进行下去。这真是愚蠢,我认为尝试向您解释如何编写单元测试以测试您的方法是否返回了任何误导性值并写入日志消息,对我来说没有什么用。我认为没有人会真正想要这种行为。

使您的方法抛出错误,并且可以轻松地确认它是通过junit完成的。给它自己的测试方法并注释:

@Test(expected = IOException.class)
public void testSomething() {
    if (Boolean.TRUE) throw new IOException();
    // this test will _PASS_,because we said
    // it SHOULD throw IOException.
}

您的意思是:如何使此方法抛出IOException?

这是不容易实现的,除非您破坏了使之成为可能的方法。如果您停止捕获异常并将其变成愚蠢的事情(一条日志消息并继续执行代码),则代码覆盖范围不再是问题。只是完全摆脱那些捕获块。