【问题标题】:Attempting to parse XML using SAX, but none of my JUnit tests work?尝试使用 SAX 解析 XML,但我的 JUnit 测试都不起作用?
【发布时间】:2014-04-25 16:50:18
【问题描述】:

所以我正在尝试运行各种测试来检查我的 XML 解析是否正确。不幸的是,我认为它们都没有通过,这是因为我的 XML 文件没有正确存储到 ArrayList 中。如有任何帮助,我将不胜感激!

视频文件.java:

package server;

public class VideoFile {
    private int id;
    private String title;
    private String filename;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getFilename() {
        return filename;
    }
    public void setFilename(String filename) {
        this.filename = filename;
    }  
}

XMLReader.java:

package server;


import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;



public class XMLReader extends DefaultHandler {

    //List to hold VideoFiles object
    private List<VideoFile> videoList = null;
    private VideoFile emp = null;


    //getter method for employee list
    public List<VideoFile> getList() {
        return videoList;
    }


    boolean bTitle = false;
    boolean bFilename = false;


    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {

        if (qName.equalsIgnoreCase("video")) {
            //create a new VideoFile and put it in Map
            String id = attributes.getValue("id");
            //initialize VideoFile object and set id attribute
            emp = new VideoFile();
            emp.setId(Integer.parseInt(id));
            //initialize list
            if (videoList == null)
                videoList = new ArrayList<>();
        } else if (qName.equalsIgnoreCase("title")) {
            //set boolean values for fields, will be used in setting VideoFile variables
            bTitle = true;
        } else if (qName.equalsIgnoreCase("filename")) {
            bFilename = true;
        }    
    }


    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equalsIgnoreCase("video")) {
            //add VideoFile object to list
            videoList.add(emp);
        }
    }


    @Override
    public void characters(char ch[], int start, int length) throws SAXException {

        if (bTitle) {
            emp.setTitle(new String(ch, start, length));
            bTitle = false;
        } else if (bFilename) {
            emp.setFilename(new String(ch, start, length));
            bFilename = false;
        }
    }

    public static void main(String[] args) {
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    try {
        SAXParser saxParser = saxParserFactory.newSAXParser();
        XMLReader handler = new XMLReader();
        saxParser.parse(new File("videoList.xml"), handler);
        //Get VideoFiles list
        List<VideoFile> videoList = handler.getList();
        //print employee information
        for(VideoFile emp : videoList)
            System.out.println(emp);
    } catch (ParserConfigurationException | SAXException | IOException e) {
        e.printStackTrace();
    }
    }
}

XMLReaderTest.java:

package server;

import static org.junit.Assert.*;
import java.util.List;
import org.junit.Before;
import org.junit.Test;

public class XMLReaderTest {
    private XMLReader reader;
    private List<VideoFile> videoList;

    @Before
    public void setUp() throws Exception {
        reader = new XMLReader();
        videoList = reader.getList();
    }

    @Test
    public void createListOfVideos() {
        assertTrue(videoList instanceof List);
    }

    @Test
    public void listContainsVideoFiles() {
        assertTrue(videoList.get(0) instanceof VideoFile);
    }

    @Test
    public void videoFileReturnsCorrectFields() {
        VideoFile videoFile = videoList.get(0);
        assertNotNull(videoFile.getId());
        assertNotNull(videoFile.getTitle());
        assertNotNull(videoFile.getFilename());
    }

    @Test
    public void videoFileReturnsCorrectData() {
        VideoFile videoFile = videoList.get(0);
        assertEquals("201202132", videoFile.getId());
        assertEquals("Monsters Inc.", videoFile.getTitle());
        assertEquals("monstersinc_high.mpg", videoFile.getFilename());
    }
}

videoList.xml:

<?xml version="1.0"?>
<videoList version="sample">
    <video id="4352524242">
        <title>Video 1</title>
        <filename>vid1_high.mpg</filename>
    </video>
    <video id="20120102b7">
        <title>Video 2</title>
        <filename>vid2-featurehp.mp4</filename>
    </video>
    <video id="1242102b7">
        <title>Vid3</title>
        <filename>vid3-featureukFhp.mp4</filename>
    </video>
</videoList>

【问题讨论】:

  • 使用 JAXB,您的代码会简单得多。

标签: java xml junit sax


【解决方案1】:

您的测试失败了,因为您的代码没有解析 XML,并且您的视频列表为空。您的 XML 文档有效,但解析它的代码没有运行。

解析 XML 文档的唯一代码在 XMLReadermain 方法中。因为XMLReader 不是主类(主类将是一个JUnit 测试运行器类),所以它的main 方法被忽略了。

将 XML 处理代码移出 main 方法并确保您的测试调用它。

【讨论】:

  • 抱歉回复,感谢您的帮助!我已经更新了代码,现在它可以完美执行。现在进入测试,我的讲师所做的对我来说不太有意义。我不明白为什么他在 XMLReader 中已经加载了 XML 文件时又单独加载它?如何使用测试用例与生成的 ArrayList 进行比较,而不是直接与文件进行比较?
  • @user1929131:对不起,我不明白你的评论。您的测试正在与从 XMLReader 返回的 ArrayList 进行比较。
  • 似乎测试实际上不起作用,这让我感到困惑。所以第一个测试 createListOfVideos 失败了,但所有其他测试都给出了错误。错误似乎是因为: VideoFile videoFile = videoList.get(0);这意味着它不能返回所述索引处的元素?
  • 会不会是因为在测试运行时,实际上并没有创建List,因为主要代码还没有运行?
  • @user1929131:未创建列表。如果videoList instanceof List 为假,则videoList 必须为null。您的其他测试将报告错误,因为您没有任何可以从中读取视频文件的列表。如果解析 XML 的代码仍在 main 中,那么在您运行测试时它不会运行,因为您的 main 方法中的代码只有在您直接运行 XMLReaderTest 时才会运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 2014-04-19
  • 2015-12-28
  • 2018-03-10
  • 1970-01-01
  • 2012-02-07
相关资源
最近更新 更多