我正在用Java编程,而我的应用程序正在大量使用DB。因此,对我来说重要的是能够轻松测试数据库的使用情况。
什么是DB测试?对我来说,他们应该提供两个简单的要求:
那么,看来我只需要一个DB。
但实际上,我不喜欢这样做,因为使用数据库进行测试几乎没有困难:
因此,您可以发现测试时我不喜欢DB(当然,在某些时候,我必须要解决这个问题,但是在发现大多数错误是通过使用其余的测试方法)。但是我在找什么呢?
我正在寻找一种使用文件系统或仅使用虚拟内存来模拟数据库,模拟数据库的方法。我以为可能有一个Java工具/软件包,可以允许每个测试简单地(使用代码接口)构造一个数据库模拟,模拟表和行,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;
}
我希望这段代码足够清楚,可以理解我的想法(对我来说,语法错误,请输入我没有亲爱的Eclipse:P的手动代码)。
顺便说一下,我部分使用ORM,而我的原始SQL查询非常简单,并且在一个平台与另一个平台之间应该没有什么不同。
对旧问题的新答案(但情况有所发展):
如何模拟要测试的数据库(Java)?
您不会模拟它。您嘲笑您的存储库,但不对其进行测试,或者在测试中使用相同的数据库,然后对sql进行测试。所有内存数据库都不完全兼容,因此它们不会为您提供全面的覆盖范围和可靠性。永远不要尝试模拟/模拟连接,结果集等深层db对象。它根本没有任何价值,是开发和维护的噩梦
拥有个人测试数据库几乎是不可能的。您必须使用一个“公共”数据库,每个人都可以使用
不幸的是,许多公司仍然使用该模型,但是现在我们有了docker,几乎每个数据库都有映像。商业产品有一些局限性(例如,高达几GB的数据)对于测试而言并不重要。您还需要在此本地数据库上创建架构和结构
“这些测试肯定不会很快…”-DB测试往往比常规测试慢。进行缓慢的测试真的不理想。
是的,数据库测试速度较慢,但并不是那么慢。我做了一些简单的测量,一个典型的测试用了5-50ms。需要时间的是应用程序启动。有很多方法可以加快速度:
您也可以将整个数据库放入tmpfs
另一个有用的策略是设置测试组,并在默认情况下关闭数据库测试(如果它们确实减慢了构建速度)。这样,如果某人实际上正在处理db,则需要在cmd行中传递其他标志或使用IDE(testng组和自定义测试选择器非常适合此操作)
对于每种情况,都应进行一定数量的插入/更新查询,这很烦人并且需要时间
上面讨论了“花时间”部分。讨厌吗 我看过两种方法:
count(*)
的测试B会失败。它之所以增长是因为即使删除了一些测试,您也不知道该测试仅使用了哪些行您怎么知道该表中有542行?”-测试的主要原则之一就是能够以与测试代码不同的方式测试功能
嗯…不是真的。主要原理是检查您的软件是否响应特定输入生成了所需的输出。因此,如果您拨打dao.insert
542次,然后dao.count
返回542,则表示您的软件按指定方式工作。如果需要,可以在两者之间调用提交/删除缓存。当然,有时您想测试实现而不是合同,然后检查dao是否更改了数据库的状态。但您始终使用sql
B测试sql A(插入vs选择,序列next_val vs返回值等)。是的,您始终会遇到“谁将测试我的测试”的问题,答案是:没有人,因此请保持简单!
其他可能帮助您的工具:
testcontainers将帮助您提供真实的数据库。
dbunit-将帮助您清除测试之间的数据
缺点:
* 创建和维护架构和数据需要大量工作。特别是在您的项目处于密集开发阶段时。
* 这是另一个抽象层,因此,如果您突然想使用此工具不支持的某些数据库功能,可能很难对其进行测试
缺点:
* 仅针对小型项目免费
* 非常年轻的项目
由于一个人在单元测试和模拟之前没有经验,我使用Mockito学习了关于JUnit的初学者教程,并进行了一些实践。 现在,我需要对一些在MySQL数据库上执行基本数据库操作的类方法进行单元测试。我不想对数据库进行真正的更改。 在不访问真实数据库的情况下,是否存在验证类似方法的方法?还是我误解了单元测试和嘲笑的概念?
问题内容: 我对Spring还是很陌生,想知道如何创建使用模拟数据源的JUnit测试以及如何在其中使用JNDI上下文?当前,我的应用程序使用来自tomcat的JNDI上下文来检索连接,并通过该连接从数据库中检索数据。所以我想我需要模拟JNDI调用和数据检索。关于解决此问题的最佳方法的任何很好的指示都是很棒的!非常感谢! 问题答案: 我通常在单独的文件中定义我的JNDI依赖项,例如: 这样,在测试资
我正在尝试对服务方法进行单元测试。服务方法调用spring数据存储库方法来获取一些数据。我想模拟这个存储库调用,并自己提供数据。如何做到这一点?在Spring Boot文档之后,当我模拟存储库并在测试代码中直接调用存储库方法时,模拟工作正常。但是,当我调用服务方法时,反过来调用存储库方法,mocking就不起作用了。下面是示例代码: 服务级别: 测试等级:
我想测试一个注入数据源bean的类,但我不知道如何模拟bean数据源(我没有类,只有bean配置)。我的班级是这样的: 我的豆子:
问题内容: 我有一个Java命令行程序。我想创建JUnit测试用例以进行模拟。因为当我的程序运行时,它将进入while循环并等待用户输入。如何在JUnit中模拟呢? 问题答案: 从技术上讲,可以进行切换,但是总的来说,不直接在代码中调用它,而是添加一层间接层,这样输入源就可以从应用程序的某个位置进行控制,这样会更健壮。确切地讲,这是实现的详细信息-依赖项注入的建议很好,但是你不一定需要引入第三方框
已删除MyTestConfig.class,但问题仍然相同。即使我使用@SpringBootTest(classes={Application.Class,MyProblematicServiceImpl.Class}),它仍然在自动连线的地方返回模拟对象。MyProblematicServiceImpl是用@Service注释的空类。