Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何模拟DB进行测试(Java)?_Java_Database_Unit Testing_Testing_Jdbc - Fatal编程技术网

如何模拟DB进行测试(Java)?

如何模拟DB进行测试(Java)?,java,database,unit-testing,testing,jdbc,Java,Database,Unit Testing,Testing,Jdbc,我用Java编程,我的应用程序大量使用DB。因此,能够轻松测试我的数据库使用情况对我来说很重要。 DB测试都是关于什么的?对我来说,他们应该提供两个简单的要求: 验证SQL语法 更重要的是,检查数据是否根据给定情况正确选择/更新/插入 那么,看来我只需要一个DB。 但实际上,我不希望这样,因为使用DB进行测试没有什么困难: “给自己准备一个测试数据库,有多难?”-好吧,在我的工作场所,拥有一个个人测试数据库是不可能的。您必须使用“公共”数据库,每个人都可以访问它 “这些测试肯定不是很快……”D

我用Java编程,我的应用程序大量使用DB。因此,能够轻松测试我的数据库使用情况对我来说很重要。
DB测试都是关于什么的?对我来说,他们应该提供两个简单的要求:

  • 验证SQL语法
  • 更重要的是,检查数据是否根据给定情况正确选择/更新/插入 那么,看来我只需要一个DB。
    但实际上,我不希望这样,因为使用DB进行测试没有什么困难:

    • “给自己准备一个测试数据库,有多难?”-好吧,在我的工作场所,拥有一个个人测试数据库是不可能的。您必须使用“公共”数据库,每个人都可以访问它
    • “这些测试肯定不是很快……”DB测试往往比普通测试慢。进行缓慢的测试确实不理想
    • “这个程序应该可以处理任何情况!”-它变得有些烦人,甚至不可能在DB中尝试和模拟每个情况。对于每种情况,都应该进行一定量的插入/更新查询,这很烦人,而且需要时间
    • “等一下,你怎么知道这个表中有542行?”-测试的主要原则之一,是能够以不同于测试代码的方式测试功能。当使用DB时,通常有一种方法来做某事,因此测试与核心代码完全相同
    所以,当涉及到测试时,您可以发现我不喜欢DBs(当然,我将不得不在某个时候谈到这一点,但我宁愿在稍后的测试中,在我使用其余的测试方法发现大多数bug之后,再到那里)。但是我在找什么呢

    我正在寻找一种使用文件系统或虚拟内存来模拟DB、模拟DB的方法。我认为可能有一个Java工具/包,它允许(使用代码接口)简单地为每个测试构造一个DB模拟,带有模拟的表和行,带有SQL验证,以及用于监视其状态的代码接口(而不是使用SQL)

    你熟悉这种工具吗


    编辑:谢谢您的回答!虽然我想要一个工具,但你也给了我一些关于这个问题的提示:)我需要一些时间来查看你的报价,所以我现在不能说你的答案是否令人满意

    无论如何,这里有一个更好的视图来说明我要查找的内容—假设一个名为DBMonitor的类,它的一个特性是查找表中的行数。下面是我想如何使用JUnit测试该功能的虚构代码:

    public class TestDBMonitor extends TestCase {
    
        @Override
        public void setUp() throws Exception {
    
           MockConnection connection = new MockConnection();
    
           this.tableName = "table1";
           MockTable table = new MockTable(tableName);
    
           String columnName = "column1";
           ColumnType columnType = ColumnType.NUMBER;
           int columnSize = 50;
           MockColumn column = new MockColumn(columnName, columnType, columnSize);
           table.addColumn(column);
    
           for (int i = 0; i < 20; i++) {
               HashMap<MockColumn, Object> fields = new HashMap<MockColumn, Object>();
               fields.put(column, i);
               table.addRow(fields);
           }
    
           this.connection = connection;
        }
    
        @Test
        public void testGatherStatistics() throws Exception {
    
           DBMonitor monitor = new DBMonitor(connection);
           monitor.gatherStatistics();
           assertEquals(((MockConnection) connection).getNumberOfRows(tableName),
                        monitor.getNumberOfRows(tableName));
        }
    
        String tableName;
        Connection connection;
    }
    
    公共类TestDBMonitor扩展了TestCase{
    @凌驾
    public void setUp()引发异常{
    MockConnection连接=新的MockConnection();
    this.tableName=“table1”;
    模拟表格=新模拟表格(表格名称);
    字符串columnName=“column1”;
    ColumnType ColumnType=ColumnType.NUMBER;
    int columnSize=50;
    MockColumn column=新的MockColumn(columnName、columnType、columnSize);
    表.添加列(列);
    对于(int i=0;i<20;i++){
    HashMap字段=新的HashMap();
    字段。put(第i列);
    表.addRow(字段);
    }
    这个连接=连接;
    }
    @试验
    public void testGatherStatistics()引发异常{
    DBMonitor monitor=新的DBMonitor(连接);
    monitor.gatherStatistics();
    assertEquals(((MockConnection)connection).getNumberOfRows(tableName),
    monitor.getNumberOfRows(tableName));
    }
    字符串表名;
    连接;
    }
    
    我希望这段代码足够清晰,能够理解我的想法(请原谅语法错误,我是在没有我亲爱的Eclipse:p的情况下手动键入的)

    顺便说一句,我部分使用了ORM,我的原始SQL查询非常简单,不同平台之间不应该有所不同

    我已经用过了。基本上,它是一个JAR文件(一个纯Java内存数据库),您可以在它自己的JVM或您自己的JVM中运行,当它运行时,您有一个数据库。然后停止它,数据库就会消失。到目前为止,我把它作为一个纯内存数据库使用。运行单元测试时,通过Ant启动和停止非常简单。

    Java随附

    也就是说,我建议不要使用与生产中使用的不同类型的DB,除非您使用ORM层。否则,您的SQL可能不会像您想象的那样跨平台


    另外,首先,您是否使用ORM层访问数据库?
    如果不是:那么你所想的就没有用了。当你不确定你正在激发的SQL是否能在生产中与你的DB一起工作时,测试有什么用,就像在测试用例中你正在使用其他东西一样。

    如果是:那么您可以查看指出的各种选项。

    我们正在创建一个数据库测试环境。我们觉得我们必须使用一个带有模拟数据的真实数据库管理系统。模拟DBMS的一个问题是SQL从来没有真正完全固定为标准,因此人工测试环境必须忠实地支持生产数据库的方言。另一个问题是,我们广泛使用列值约束、外键约束和唯一约束,由于人工工具可能无法实现这些约束,我们的单元测试可能会通过,但当系统测试第一次遇到真正的约束时就会失败。如果测试花费的时间太长,这表明存在实现错误,我们将调整查询(通常测试数据集与生产数据集相比非常小)

    我们已经在每台开发人员机器以及持续集成和测试服务器(我们使用Hudson)上安装了一个真正的DBMS。我不知道您的工作策略限制是什么,但是安装和使用PostgreSQL、MySQL和Oracle X非常容易
    import static java.lang.System.out;
    import java.sql.*;
    import org.jooq.tools.jdbc.*;
    
    public class Mocking {
        public static void main(String[] args) throws Exception {
            MockDataProvider db = new MockFileDatabase(
                Mocking.class.getResourceAsStream("/mocking.txt");
    
            try (Connection c = new MockConnection(db));
                Statement s = c.createStatement()) {
    
                out.println("Actors:");
                out.println("-------");
                try (ResultSet rs = s.executeQuery(
                    "select first_name, last_name from actor")) {
                    while (rs.next())
                        out.println(rs.getString(1) 
                            + " " + rs.getString(2));
                }
            }
        }
    }