我可以使用哪些库将 POJO 绑定到 TDD 的外部文件而无需太多开销?

Posted

技术标签:

【中文标题】我可以使用哪些库将 POJO 绑定到 TDD 的外部文件而无需太多开销?【英文标题】:What libs can I use to bind POJOs to external files for TDD without much overhead? 【发布时间】:2010-09-16 18:36:07 【问题描述】:

我需要一种将 POJO 对象绑定到外部实体的方法,可以是 XML、YAML、结构化文本或任何易于编写和维护的东西,以便为单元测试和 TDD 创建 Mock 数据。以下是我尝试过的一些库,但它们的主要问题是我被困在 Java 1.4 上(至少 3 个月以上)。我想了解我可以使用什么,尽可能低的开销和前期设置(例如使用模式或 DTD)并且没有复杂的 XML。这是我真正喜欢的库(但显然不适用于 1.4 或不支持构造函数 - 你必须有设置器):

RE-JAXB(或真正简单的 Java XML 绑定)

http://jvalentino.blogspot.com/2008/07/in-response-to-easiest-java-xml-binding.html http://sourceforge.net/projects/rejaxb/

Seamlessy 绑定这个:

<item>
    <title>Astronauts' Dirty Laundry</title>
    <link>http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp</link>
    <description>Compared to earlier spacecraft, the International Space
    Station has many luxuries, but laundry facilities are not one of them.
    Instead, astronauts have other options.</description>
    <pubDate>Tue, 20 May 2003 08:56:02 GMT</pubDate>
    <guid>http://liftoff.msfc.nasa.gov/2003/05/20.html#item570</guid>
</item>

到这里:

@ClassXmlNodeName("item")
public class Item 
 private String title;
 private String link;
 private String description;
     private String pubDate;
     private String guid;

     //getters and settings go here... 

使用:

Rss rss = new Rss();
XmlBinderFactory.newInstance().bind(rss, new File("Rss2Test.xml"));

问题:它依赖于注解,所以对 Java 1.4 没有好处

jYaml http://jyaml.sourceforge.net/

无缝绑定:

--- !user
name: Felipe Coury
password: felipe
modules: 
   - !module
     id: 1
     name: Main Menu
     admin: !user
    name: Admin
    password: password

到这里:

public class User 
    private String name;
    private String password;
    private List modules;


public class Module 
    private int id;
    private String name;
    private User admin;

使用:

YamlReader reader = new YamlReader(new FileReader("example.yaml"));
reader.getConfig().setClassTag("user", User.class);
reader.getConfig().setClassTag("module", Module.class);
User user = (User) reader.read(User.class);

问题:它不适用于构造函数(因此对不可变对象没有好处)。我必须更改我的对象或编写自定义代码来处理 YAML 解析。

请记住,我想尽可能避免 - 编写数据描述符,我想要一些“正常工作”的东西。

你有什么建议吗?

【问题讨论】:

【参考方案1】:

如果要填充的对象是简单的 bean,那么查看 apache common 的 BeanUtils 类可能是个好主意。 populate() 方法可能适合所描述的情况。一般来说,像 Spring 这样的依赖注入框架可能非常有用,但这可能无法解决当前的问题。对于 xml 形式的输入,jibx 可能是一个不错的选择,jaxb 1.0 也是如此。

【讨论】:

只是简单的看了一下和jibx,好像还挺简单的,我再看看。现在谢谢。【参考方案2】:

只需使用 XStream(对于 XML,或者您可以尝试使用 JSON)。

但是……

伙计,我无法避免认为将测试数据放在单元测试本身之外会导致您无法阅读测试。读取测试用例时需要查看两个文件,您将丢失重构工具(更改属性名称时)。 Jay Fields 可以比我更好地解释它:

http://blog.jayfields.com/2007/06/testing-inline-setup.html

亲切的问候

【讨论】:

正是我对我的团队的观点!但他们坚持。我目前使用 Fluent Interfaces 与 Builder 模式混合,并且(至少我)喜欢它! :-)【参考方案3】:

你可以试试Java1.4平台默认添加的XMLEncoder/XMLDecoder

这是我使用它的方式。

import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ToXml 

    /**
     * Write an object to a file in XML format.
     * @param o - The object to serialize.
     * @param file - The file where to write the object.
     */
    public static void writeObject( Object o, String file  ) 
       XMLEncoder e = null;
       try 

           e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream(file)));

           e.writeObject(o);

       catch( IOException ioe ) 
           throw new RuntimeException( ioe );
       finally
           if( e != null ) 
               e.close();
           
       
    

    /**
     * Read a xml serialized object from the specified file.
     * @param file - The file where the serialized xml version of the object is.
     * @return  The object represented by the xmlfile.
     */
    public static Object readObject( String file )
       XMLDecoder d = null;
       try 

           d = new XMLDecoder( new BufferedInputStream( new FileInputStream(file)));

           return  d.readObject();

       catch( IOException ioe ) 
           throw new RuntimeException( ioe );
       finally
           if( d != null ) 
               d.close();
           
       
    

很简单,很简单,在核心库中。

您只需要编写加载机制。

我有这个 Swing 应用程序,它可以在 5 到 10 秒内从远程 EJB 加载数据。我所做的是像这样将上一个会话存储在 XML 中,当应用程序加载时,它会在不到 1 秒的时间内获得上一个会话的所有数据。

当用户开始使用应用程序时,后台线程会获取自上次会话以来发生更改的那些元素。

【讨论】:

以上是关于我可以使用哪些库将 POJO 绑定到 TDD 的外部文件而无需太多开销?的主要内容,如果未能解决你的问题,请参考以下文章

具有完整 POJO 数据绑定的杰克逊自定义过滤器

TDD:您为单元测试公开了哪些方法?

如何使用GSON配置哪些POJO字段序列化为JSON?

将 json 字段绑定到 POJO 中具有不同名称的字段的注解

使用 jackson-dataformat-xml 库将 XML 中的空标签转换为 java 属性

SpringMVC详解