使用数据填充ResultSet的简便方法

使用数据填充ResultSet的简便方法

本文介绍了使用数据填充ResultSet的简便方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想模拟一个ResultSet。认真。
我正在重构一个从ResultSet中解析数据的大型复杂代码,我希望我的代码行为相同。所以,我需要为重构的部分编写一个单元测试,以便能够对此进行测试。

I want to mock a ResultSet. Seriously.I'm refactoring one big complicated piece of code which is parsing data from ResultSet, and I want my code to behave identically. So, I need to write a unit test for the piece being refactored to be able to test this.

谷歌搜索后我提出了2个想法:

After googling I came up with 2 ideas:


  1. 使用EasyMock,编写looooong模拟序列。非常糟糕的解决方案:很难添加初始数据,难以更改数据,很难测试调试。

  2. 使用Apache Derby或HSQLDB创建内存数据库,从文件或字符串数​​组填充,查询一些神奇的InMemoryDBUtils.query(sql)。然后使用该ResultSet。不幸的是,我没有找到任何神奇的InMemoryDBUtils来快速编写测试:-)。 IBM的文章使用Derby进行持久性的隔离单元测试似乎对我需要的东西很好,但是...

第二种方法看起来有点更简单,更可支持。

Second approach looks somewhat easier and much more supportable.

您对创建此类模拟有何建议? (尽管医生,当然:-)?我错过了一些银弹吗?可能,DBUnit是这个的工具吗?

What would you advice for creating such a mock? (despite doctors, of course :-)? Am I missing some silver bullet? Possibly, DBUnit is the tool for this?

推荐答案

据我所知,DBUnit不提供结果集,尽管它会很好地帮助你填充你的内存数据库。

DBUnit doesn't present a result set, to my knowledge, although it will well help you populate your in memory database.

我想说一个模拟框架在这一点上是错误的方法。模拟是关于测试行为和交互,而不仅仅是返回数据,所以它可能会妨碍你。

I would say that a mocking framework is the wrong approach at this point. Mocking is about testing behavior and interaction, not just returning data, so it will likely get in your way.

我会改为实现结果集接口,或创建一个结果集接口的动态代理,实现您关心的方法的类,而不必实现整个结果集。您可能会发现维护一个类就像维护内存数据库一样简单(只要测试的数据集是一致的),并且可能更容易调试。

I would instead either implement a result set interface, or create a dynamic proxy of a result set interface to a class that implements the methods you care about without having to implement the whole result set. You will likely find maintaining a class as easy as maintaining an in memory database (provided that the dataset under test is consistent), and probably easier to debug.

你可以回来使用DBUnit创建该类,使用dbunit获取结果集的快照,并让dbunit在测试期间从xml读取它,并让您的虚拟结果集读取dbunit类的数据。如果数据有点复杂,这将是一种合理的方法。

You could back up that class with DBUnit, where you take a snapshot of your result set with dbunit, and have dbunit read it back during the test from xml, and have your dummy result set read the data from dbunit's classes. This would be a reasonable approach if the data was mildly complex.

如果类是如此耦合以至于他们需要读取数据,我会选择内存数据库作为同一测试的一部分进行修改。即便如此,我还是会考虑使用真实数据库的副本,直到你设法将这种依赖性分开。

I would go for the in memory database if the classes were so coupled that they need to read data that was modified as part of the same test. Even then, I would consider using a copy of the real database until you managed to pull that dependency apart.

一种简单的代理生成方法:

A simple proxy generation method:

private static class SimpleInvocationHandler implements InvocationHandler {
    private Object invokee;

    public SimpleInvocationHandler(Object invokee) {
        this.invokee = invokee;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        method = invokee.getClass().getMethod(method.getName(), method.getParameterTypes());
        if (!method.isAccessible()) {
            method.setAccessible(true);
        }
        try {
            return method.invoke(invokee, args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }
}

public static <T> T generateProxy(Object realObject, Class... interfaces) {
    return (T) Proxy.newProxyInstance(realObject.getClass().getClassLoader(), interfaces, new SimpleInvocationHandler(realObject));
}

这篇关于使用数据填充ResultSet的简便方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 14:58