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

发布于 2024-07-07 07:27:35 字数 2860 浏览 4 评论 0原文

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

RE-JAXB(或Really Easy Java XML Bindings)

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

无缝绑定此:

<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 解析。

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

你有什么建议吗?

I need a way to bind POJO objects to an external entity, that could be XML, YAML, structured text or anything easy to write and maintain in order to create Mock data for unit testing and TDD. Below are some libraries I tried, but the main problems with them were that I am stuck (for at least more 3 months) to Java 1.4. I'd like any insights on what I could use instead, with as low overhead and upfront setup (like using Schemas or DTDs, for instance) as possible and without complex XML. Here are the libraries I really like (but that apparently doesn't work with 1.4 or doesn't support constructors - you gotta have setters):

RE-JAXB (or Really Easy Java XML Bindings)

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

Seamlessy binds this:

<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>

To this:

@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... 
}

Using:

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

Problem: It relies on annotations, so no good for Java 1.4

jYaml
http://jyaml.sourceforge.net/

Seamlessly binds this:

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

To this:

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

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

Using:

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);

Problem: It won't work with constructors (so no good for immutable objects). I'd have to either change my objects or write custom code por handling the YAML parsing.

Remember that I would like to avoid - as much as I can - writing data descriptors, I'd like something that "just works".

Do you have any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

送君千里 2024-07-14 07:27:35

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

If the objects to be populated are simple beans it may be a good idea to look at apache common's BeanUtils class. The populate() method might suit the described cases. Generally dependency injection frameworks like Spring can be very useful, but that might not be answer for the current problem. For input in form of xml, jibx might be a good alternative, so would be jaxb 1.0.

遗心遗梦遗幸福 2024-07-14 07:27:35

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

但是...

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

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

亲切的问候

Just use XStream (for XML or you could give a try to JSON).

But...

Man, I just can't avoid to think that put the test data outside the unit test itself will leads you to unreadable tests. You will need look two files when reading a test case, you will lose refactoring tools (when changing property's name). Jay Fields can explain it better than me:

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

Kind Regards

夏了南城 2024-07-14 07:27:35

你可以尝试一下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 秒的时间内获得上一个会话的所有数据。

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

You may give it a try to the deefault XMLEncoder/XMLDecoder that was added to the platform in Java1.4

Here's the way I use it.

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();
           }
       }
    }

}

It's easy, is simple, is in the core libraries.

You just have to write the load mechanism.

I have this swing app that loads data from a remote EJB in 5 - 10 secs. What I do is to store the previous session in XML like this and when the app loads it has all the data from the previous session in less than 1 sec.

While the user start to work with the app, a background thread fetches those elements that have changed since the last session.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文