如何为我用Java编写的XML解析器编写单元测试

时间:2014-05-09 14:19:18

标签: java xml unit-testing junit

背景如下:

我有代表推文的对象(来自Twitter)。每个对象都有一个id,一个日期和原始推文的id(如果有的话)。

我收到一条推文文件(其中每条推文的格式为05/04/2014 12:00:00, tweetID, originalID并且在其自己的行中)我希望将它们保存为XML文件,其中每个字段都有自己的标记。

我希望能够读取该文件并从XML文件中返回与推文相对应的Tweet个对象列表。

在编写执行此操作的XML解析器之后,我想测试它是否正常工作。我不知道如何测试这个。

XML Parser:

public class TweetToXMLConverter implements TweetImporterExporter {
    //there is a single file used for the tweets database
    static final String xmlPath = "src/main/resources/tweetsDataBase.xml";
    //some "defines", as we like to call them ;)
    static final String DB_HEADER = "tweetDataBase";
    static final String TWEET_HEADER = "tweet";
    static final String TWEET_ID_FIELD = "id";
    static final String TWEET_ORIGIN_ID_FIELD = "original tweet";
    static final String TWEET_DATE_FIELD = "tweet date";
    static File xmlFile;
    static boolean initialized = false;

    @Override
    public void createDB() {
        try {
            Element tweetDB = new Element(DB_HEADER);
            Document doc = new Document(tweetDB);
            doc.setRootElement(tweetDB);

            XMLOutputter xmlOutput = new XMLOutputter();

            // display nice nice? WTF does that chinese whacko want?
            xmlOutput.setFormat(Format.getPrettyFormat());
            xmlOutput.output(doc, new FileWriter(xmlPath));
            xmlFile = new File(xmlPath);
            initialized = true;

        } catch (IOException io) {
            System.out.println(io.getMessage());
        }
    }

    @Override
    public void addTweet(Tweet tweet) {
        if (!initialized) {
            //TODO throw an exception? should not come to pass!
            return;
        }
        SAXBuilder builder = new SAXBuilder();
        try {
            Document document = (Document) builder.build(xmlFile);

            Element newTweet = new Element(TWEET_HEADER);
            newTweet.setAttribute(new Attribute(TWEET_ID_FIELD, tweet.getTweetID()));
            newTweet.setAttribute(new Attribute(TWEET_DATE_FIELD, tweet.getDate().toString()));
            if (tweet.isRetweet())
                newTweet.addContent(new Element(TWEET_ORIGIN_ID_FIELD).setText(tweet.getOriginalTweet()));

            document.getRootElement().addContent(newTweet);

        } catch (IOException io) {
            System.out.println(io.getMessage());
        } catch (JDOMException jdomex) {
            System.out.println(jdomex.getMessage());
        }
    }

    //break glass in case of emergency
    @Override
    public void addListOfTweets(List<Tweet> list) {
        for (Tweet t : list) {
            addTweet(t);
        }
    }

    @Override
    public List<Tweet> getListOfTweets() {
        if (!initialized) {
            //TODO throw an exception? should not come to pass!
            return null;
        }
        try {
            SAXBuilder builder = new SAXBuilder();
            Document document;
            document = (Document) builder.build(xmlFile);

            List<Tweet> $ = new ArrayList<Tweet>();
            for (Object o : document.getRootElement().getChildren(TWEET_HEADER)) {
                Element rawTweet = (Element) o;

                String id = rawTweet.getAttributeValue(TWEET_ID_FIELD);
                String original = rawTweet.getChildText(TWEET_ORIGIN_ID_FIELD);
                Date date = new Date(rawTweet.getAttributeValue(TWEET_DATE_FIELD));
                $.add(new Tweet(id, original, date));
            }
            return $;
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

一些用法:

private TweetImporterExporter converter;
List<Tweet> tweetList = converter.getListOfTweets();
for (String tweetString : lines)
    converter.addTweet(new Tweet(tweetString));

如何确保我读取的XML文件(包含推文)对应于我收到的文件(以上述形式)?

如何确保我添加到文件中的推文与我尝试添加的推文相对应?

1 个答案:

答案 0 :(得分:2)

假设您有以下型号:

public class Tweet {

    private Long id;
    private Date date;
    private Long originalTweetid;
    //getters and seters
} 

该过程如下:

  • 创建TweetToXMLConverter的意义
  • 创建解析文件后希望收到的Tweet实例列表
  • 将转换器提供给您生成的列表
  • 比较通过解析列表收到的列表和您在测试开始时创建的列表

    public class MainTest {
    
        private TweetToXMLConverter converter;
        private List<Tweet> tweets;
    
        @Before
        public void setup() {
    
            Tweet tweet = new Tweet(1, "05/04/2014 12:00:00", 2);
            Tweet tweet2 = new Tweet(2, "06/04/2014 12:00:00", 1);
            Tweet tweet3 = new Tweet(3, "07/04/2014 12:00:00", 2);
            tweets.add(tweet);
            tweets.add(tweet2);
            tweets.add(tweet3);
    
            converter = new TweetToXMLConverter();
            converter.addListOfTweets(tweets);
        }
    
        @Test
        public void testParse() {
    
            List<Tweet> parsedTweets = converter.getListOfTweets();
            Assert.assertEquals(parsedTweets.size(), tweets.size());
            for (int i=0; i<parsedTweets.size(); i++) {
                //assuming that both lists are sorted
                Assert.assertEquals(parsedTweets.get(i), tweets.get(i)); 
            };
        }
    }
    

我正在使用JUnit进行实际测试。