我试图在新的Spring Boot创建的服务类上运行测试。 StringWriter内容是常规XML,带有几行名为' transaction'的标记。
PrepareExcelServiceTest 的.class
@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
public class PrepareExcelServiceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
private static final Logger log = LoggerFactory.getLogger(PrepareExcelService.class);
@Test
public void testPrepareExcelService() throws ParserConfigurationException, SAXException, IOException {
PrepareExcelService prepareExcelService = new PrepareExcelService();
StringWriter xmlStringWriter = new StringWriter();
Source source = new StreamSource("./view/xml/0_dummy.xml");
xmlStringWriter.write(source.toString());
prepareExcelService.prepareDocument(xmlStringWriter);
}
}
PrepareExcelService 的.class
@Service
public class PrepareExcelService {
private HSSFWorkbook workbook;
private HSSFSheet spreadsheet;
public void prepareDocument(StringWriter xmlStringWriter) throws IOException,
SAXException, ParserConfigurationException {
workbook = setupWorkBook();
spreadsheet = setupSheet(workbook);
Document document = parseXMLStringWriter(xmlStringWriter);
fillContent(document, spreadsheet);
FileOutputStream output = new FileOutputStream(new File("TestExcelFile.xls"));
workbook.write(output);
output.flush();
output.close();
}
private HSSFWorkbook setupWorkBook() {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setBorderLeft(BorderStyle.MEDIUM);
cellStyle.setBorderRight(BorderStyle.MEDIUM);
cellStyle.setBorderTop(BorderStyle.MEDIUM);
cellStyle.setBorderBottom(BorderStyle.MEDIUM);
cellStyle.setIndention((short)4);
cellStyle.setWrapText(true);
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(false);
cellStyle.setFont(font);
return workbook;
}
private HSSFSheet setupSheet(HSSFWorkbook workbook) {
HSSFSheet spreadSheet = workbook.createSheet("spreadSheet");
return spreadSheet;
}
private Document parseXMLStringWriter(StringWriter xmlStringWriter) throws ParserConfigurationException,
IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(xmlStringWriter.toString());
}
private void fillContent (Document document, HSSFSheet spreadSheet) {
HSSFRow row = spreadSheet.createRow(0);
HSSFCell cell = row.createCell((short) 1);
NodeList nodeList = document.getElementsByTagName("transaction");
HSSFRow rowOne = spreadSheet.createRow(1);
cell.setCellValue("Spreadsheet Header Row");
for (int i = 0; i < nodeList.getLength(); i++) {
switch (i) {
case 0:
cell = rowOne.createCell((short) 0);
cell.setCellValue("transaction");
cell = rowOne.createCell((short) 1);
cell.setCellValue(((Element) (nodeList.item(0))).getElementsByTagName("transaction").item(0)
.getFirstChild().getNodeValue());
break;
default:
break;
}
}
}
}
在测试此服务时,我得到以下异常,尽管该文件存在,而其他服务通过StringWriter正确地与它进行交互。
java.io.FileNotFoundException: ...\javax.xml.transform.stream.StreamSource@4439f31e (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:623)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:177)
at ee.estcard.repgen.service.PrepareExcelService.parseXMLStringWriter(PrepareExcelService.java:78)
at ee.estcard.repgen.service.PrepareExcelService.prepareDocument(PrepareExcelService.java:39)
at ee.estcard.repgen.service.PrepareExcelServiceTest.testPrepareExcelService(PrepareExcelServiceTest.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.mockito.internal.junit.JUnitRule$1.evaluate(JUnitRule.java:16)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
我认为问题在于我对StringWriter的错误使用,但由于我对Java的新手知识,我仍然无法解决这个问题。
答案 0 :(得分:2)
没有问题与您使用StreamSource
的方式有关,确实调用source.toString()
不会像您期望的那样向您提供来源的内容,但是javax.xml.transform.stream.StreamSource@4439f31e
就像您一样可以在你的堆栈跟踪中看到。
只需删除您的StringWriter
并在代码中使用InputSource
来修复代码,同时也可以使其更灵活,因为使用InputSource
可以打开许多不同的代码类型的源,而且加载文件的内容不是一个好的做法,应该避免,因为如果文件太大,你可能会面对OOME,如果它不适合堆。
PrepareExcelServiceTest
PrepareExcelService prepareExcelService = new PrepareExcelService();
InputSource source = new InputSource("./view/xml/0_dummy.xml");
prepareExcelService.prepareDocument(source);
在要重命名的方法parseXMLStringWriter
private Document parseXML(InputSource source) throws ParserConfigurationException,
IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(source);
}
方法prepareDocument
public void prepareDocument(InputSource source) throws IOException,
SAXException, ParserConfigurationException {
...
Document document = parseXML(source);
...
}
答案 1 :(得分:1)
首先,我怀疑StringWriter
是用于传输“字符串内容”的方法签名的好类型。有许多替代方案,使用指针(即URI,路径,文件)到内容或角色内容的一些消费表示(Reader,InputStream,InputSourc)或内容本身(String)。
但是假设你是故意这样做的:
DocumentBuilder
的{{1}}方法接受:
parse()
InputSource
你的StringWriter或更好,它的InputStream
方法的结果都不是它们。因此,您需要将toString()
的缓冲区内容转换为任何类型的内容。
最简单的可能就是
StringWriter
所以方法可能如下:
new InputSource(new StringReader(xmlStringWriter.toString()))
现在,您可以解析编写器中包含的字符串。但是,内容仍然是错误的。
private Document parseXMLStringWriter(StringWriter xmlStringWriter) throws ParserConfigurationException,
IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(new StringReader(xmlStringWriter.toString())));
}
的{{1}}方法创建了一个对象引用字符串,但不生成StreamSource引用的文件的内容。相反,您需要获取文件的内容。
将文件内容转换为String的最简单方法可能是
StreamSource
(忽略文件的编码)
这应该让你的测试运行。但同样,请不要使用StringWriter。