Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.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
我应该如何对调用MySQL存储过程的Java进行单元测试?_Java_Mysql_Unit Testing - Fatal编程技术网

我应该如何对调用MySQL存储过程的Java进行单元测试?

我应该如何对调用MySQL存储过程的Java进行单元测试?,java,mysql,unit-testing,Java,Mysql,Unit Testing,我正在编写一个简单的应用程序,它将读取一些记录并将它们插入数据库。我已经编写了一个处理插入逻辑的存储过程,并计划单独进行测试。现在,我想为接受业务对象并将其传递给存储过程调用的逻辑部分编写一个良好的单元测试 我想我要做的是传递数据库连接的模拟,然后断言调用是使用预期的参数值进行的: Connection dbConnection = makeMockConnection(); // how? MyObjectWriter writer = new MyObjectWriter(dbConnec

我正在编写一个简单的应用程序,它将读取一些记录并将它们插入数据库。我已经编写了一个处理插入逻辑的存储过程,并计划单独进行测试。现在,我想为接受业务对象并将其传递给存储过程调用的逻辑部分编写一个良好的单元测试

我想我要做的是传递数据库连接的模拟,然后断言调用是使用预期的参数值进行的:

Connection dbConnection = makeMockConnection();  // how?
MyObjectWriter writer = new MyObjectWriter(dbConnection);
writer.write(someSampleObject);
// somehow assert that dbConnection called
// `sp_saveMyObject` with param values x, y, and z

然而,似乎需要在
java.sql.Connection
内部进行大量工作,了解它的工作原理,然后模拟所有结果。有没有一个测试库可以帮我做这些?我是不是搞错了?

您可以使用模拟存储过程创建内存中的HSSQL数据库。 模拟存储过程将在表中插入一行,以显示该行已运行以及它的参数是什么。
运行测试中的代码,然后查看数据库中发生的情况。

您可以使用Decorator设计模式进行连接模拟。使用所使用的驱动程序创建到DB的实际连接,该驱动程序由实现连接接口并将实际连接作为成员保存的ConnectionImpl类包装
您不想实际执行的每个实际调用,都用模拟代码替换它,每次调用都会调用实际连接对象的相同方法(委托调用)。
通过这种方式,您像往常一样编码,只是返回的对象与创建连接的方法有所不同。

现在,在mock对象(您的ConnectionImpl)中,您可以添加检查输入的单元测试代码。

如果您不关心MyObjectWriter的工作方式,只关心它的工作方式,那么我倾向于编写集成测试,而忽略单元测试


您没有提到如何测试存储过程,请原谅,但我要做的是围绕
MyObjectWriter
编写测试,这些测试调用数据库上的实际存储过程,然后验证数据库状态。如果可能的话,我会使用内存中的数据库来缩短测试持续时间。

模拟连接来检查是否调用了方法非常简单。您应该熟悉我正在试图避免约束业务逻辑以某种方式运行——我可以调用
Connection.createStatement
Connection.prepareStatement
Connection.prepareCall
甚至
Connection.nativeSql
,任何一种都是正确的(数据被传递到过程中)。我试图避免模拟所有这些东西,或者至少我自己编写这些模拟。这会在运行测试时产生多少开销?现在我的其余测试可以在几毫秒内运行—站立/拆卸时间是否重要?我从来没有计时过,但我猜由于我使用了临时文件,可能需要10毫秒t创建。如果您只有少数几个类型测试,您就不会担心。如果您有数千个类型测试,您可能会担心。您可以在多个测试中始终共享同一个db实例,只要您清理了它们之间的表。我使用内存dbs进行大量测试,发现简单性远远超过了执行时间。您没有要更改任何代码,只需传入一个不同的jdbc连接字符串。这是一个巨大的优势。我很难找到一个简单的入门指南——HSQLDB文档有数百页,我能找到的关于使用HSQLDB进行单元测试的大多数博文等都是针对Hibernate/Spring的ust需要启动一个数据库,添加一个表和一个存储过程,然后在我完成后将其拆下。这应该很简单,对吗?在项目中包括jar并注册jdbc驱动程序。组成一个数据库名称(例如mytestdb)和jdbc连接字符串(jdbc:h2:target/mytestdb)。通过jdbc连接时,数据库将自动创建。然后通过jdbc api使用ddl命令创建表、存储过程、插入数据等。java.sql.DriverManager.registerDriver(new org.h2.Driver());java.sql.DriverManager.getConnection(“jdbc:h2:target/mytestdb”、“test”、“test”);这里的问题是,正如我在对OP的评论中所说的,我试图不深入挖掘连接的本质。包装器必须知道要检查什么,执行过程中的什么点是完成同一件事情的4种或5种不同方法之间的共同点。这样,比@AutomatedMike的答案要复杂得多。