如何通过DocumentBuidlerFactory创建新的xml文件时生成ParserConfigurationException
我将从字符串创建XML。 看起来像
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public Document createCompleteExportXml(String xmlFilename, String content) { try { DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder(); //create the XML file here } catch (ParserConfigurationException pce) { LOGGER.trace("parsing error ", pce); } }
现在我必须测试是否可以在Junit测试中捕获exception。
@Test(expected=ParserConfigurationException.class) public void createCompleteExportXmlWithParseConfigurationException() { String xmlFilename = "junitExportTestWithParseConfigurationException.xml"; String content = "any content"; XmlFileWriter writer = new XmlFileWriter(); Document doc = writer.createCompleteExportXml(xmlFilename, content); }
如何让这个测试抛出ParserConfigurationException
?
我使我的问题更具体:如何使documentFactory.newDocumentBuilder()无法工作,因为“无法创建满足所请求配置的DocumentBuilder。”? 配置在哪里? 如何故意将其更改为错误的?
你的测试没有通过,因为你正在你的方法中捕获精确的ParserConfigurationException
,所以它永远不会被抛出。 通过测试:
1)更改方法的签名(抛出exception)
public String createCompleteExportXml(String xmlFilename, String content) throws ParserConfigurationException {
2)抛出ParserConfigurationException
。 为此,您可以删除catch块或在LOGGER.trace
之后抛出exception。 第二个选项的示例:
try { //... } catch (ParserConfigurationException pce) { LOGGER.trace("parsing error ", pce); throw pce; }
希望它能帮到你
[UPDATE]
如果要模拟ParserConfigurationException
,可以使用像Mockito / PowerMock
这样的框架来模拟DocumentBuilderFactory
并模拟在调用newDocumentBuilder()
方法时抛出ParserConfigurationException
。
例:
@RunWith(PowerMockRunner.class) @PrepareForTest(DocumentBuilderFactory.class) public class XmlFileWriterTest { @Test(expected = ParserConfigurationException.class) public void createCompleteExportXmlWithParseConfigurationException() throws Exception { String xmlFilename = "junitExportTestWithParseConfigurationException.xml"; String content = "any content"; XmlFileWriter writer = new XmlFileWriter(); // Mock DocumentBuilderFactory: When method newDocumentBuilder() is called, throws a simulated ParserConfigurationException DocumentBuilderFactory mockDocumentBuilderFactory = PowerMockito.mock(DocumentBuilderFactory.class); PowerMockito.when(mockDocumentBuilderFactory.newDocumentBuilder()).thenThrow(new ParserConfigurationException("Simulated ex")); // Mock DocumentBuilderFactory.newInstance(), when is called, returns your mock instance mockDocumentBuilderFactory PowerMockito.mockStatic(DocumentBuilderFactory.class); PowerMockito.when(DocumentBuilderFactory.newInstance()).thenReturn(mockDocumentBuilderFactory); writer.createCompleteExportXml(xmlFilename, content); }
此测试通过(完成之前的代码建议)。
powerMock的Maven依赖项:
org.powermock powermock-module-junit4 1.5.4 org.powermock powermock-api-mockito 1.5.4
希望这将是你正在寻找的。
您可以找到更多关于Mockito和PowerMock的文档
正如您在源代码中看到的:
public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { // Check that if a Schema has been specified that neither of the schema properties have been set. if (grammar != null && attributes != null) { if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_LANGUAGE)) { throw new ParserConfigurationException( SAXMessageFormatter.formatMessage(null, "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_LANGUAGE})); } else if (attributes.containsKey(JAXPConstants.JAXP_SCHEMA_SOURCE)) { throw new ParserConfigurationException( SAXMessageFormatter.formatMessage(null, "schema-already-specified", new Object[] {JAXPConstants.JAXP_SCHEMA_SOURCE})); } } try { return new DocumentBuilderImpl(this, attributes, features, fSecureProcess); } catch (SAXException se) { // Handles both SAXNotSupportedException, SAXNotRecognizedException throw new ParserConfigurationException(se.getMessage()); } }
如果模式定义了两次,则抛出ParserConfigurationException
我不认为现有的答案中的任何一个都能真正回答这个问题,所以这就是我对此的看法。
方法一,利用com.sun。*解析器内部:
(助手class)
import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import javax.xml.validation.Schema; import javax.xml.validation.Validator; import javax.xml.validation.ValidatorHandler; public class MisconfiguredDocumentBuilderFactory extends DocumentBuilderFactoryImpl { @Override public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { super.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); super.setSchema(new Schema() { @Override public Validator newValidator() { return null; } @Override public ValidatorHandler newValidatorHandler() { return null; } }); return super.newDocumentBuilder(); } }
(实际测试类)
public class OPClassTest { private final static String DOC_BUILDER_PROPERTY_NAME = "javax.xml.parsers.DocumentBuilderFactory"; @Test public void testParserConfigurationProblem() { System.setProperty(DOC_BUILDER_PROPERTY_NAME, MisconfiguredDocumentBuilderFactory.class.getCanonicalName()); targetClass.createCompleteExportXml("somefilename", "somecontent"); } @After public void tearDown() { System.clearProperty(DOC_BUILDER_PROPERTY_NAME); } }
方法2,不使用com.sun。*命名空间
(助手class)
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class MisconfiguredDocumentBuilderFactory2 extends DocumentBuilderFactory { @Override public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { throw new ParserConfigurationException( "this factory is not configured properly"); } @Override public void setAttribute(String name, Object value) throws IllegalArgumentException { // no-op } @Override public Object getAttribute(String name) throws IllegalArgumentException { return null; } @Override public void setFeature(String name, boolean value) throws ParserConfigurationException { // no-op } @Override public boolean getFeature(String name) throws ParserConfigurationException { return false; } }
(实际测试类)
public class OPClassTest { private final static String DOC_BUILDER_PROPERTY_NAME = "javax.xml.parsers.DocumentBuilderFactory"; @Test public void testParserConfigurationProblem() { System.setProperty(DOC_BUILDER_PROPERTY_NAME, MisconfiguredDocumentBuilderFactory2.class.getCanonicalName()); targetClass.createCompleteExportXml("somefilename", "somecontent"); } @After public void tearDown() { System.clearProperty(DOC_BUILDER_PROPERTY_NAME); } }