简体   繁体   English

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

[英]How should I unit test Java that calls a MySQL stored procedure?

I'm writing a simple application that will read some records and insert them in a database. 我正在编写一个简单的应用程序,它将读取一些记录并将其插入数据库中。 I've written a stored procedure that handles the insertion logic, and plan to test that separately. 我已经编写了一个处理插入逻辑的存储过程,并计划单独进行测试。 Now I'd like to write a good unit test for the portion of the logic that takes a business object and passes it to the stored procedure call. 现在,我想为采用业务对象并将其传递给存储过程调用的逻辑部分编写一个良好的单元测试。

I think what I want to do is pass a mock of the database connection, then assert that the call is made with expected parameter values: 认为我想做的是传递数据库连接的模拟,然后断言该调用是使用预期的参数值进行的:

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

However, it seems like a lot of work dig around inside java.sql.Connection , understand how it works, then mock all the results. 但是,似乎在java.sql.Connection内部进行了大量工作,了解了它的工作原理,然后模拟了所有结果。 Is there a test library that does all this for me? 是否有一个为我完成所有这些工作的测试库? Am I coming at this the wrong way? 我走错路了吗?

You could create an in-memory HSSQL database with a mock stored procedure. 您可以使用模拟存储过程创建内存中的HSSQL数据库。 The mock sproc would insert a row into a table to show that it ran and what it's parameters were. 模拟存储过程将在表中插入一行,以显示其已运行及其参数。 Run the code under test and then look in the db to see what happened. 运行被测代码,然后在数据库中查看发生了什么。

You can use the Decorator design pattern for the connection mocking. 您可以使用Decorator设计模式进行连接模拟。 You create a real Connection to the DB with the driver you use which is wrapped by your ConnectionImpl class that implements Connection interface and holds the real Connection as a member. 使用您使用的驱动程序创建与数据库的真实连接,该驱动程序由实现Connection接口并将Connection保留为成员的ConnectionImpl类包装。
Every real call that you don't want to actually do, replace it with a mock code, and every call the stays call the real connection object's identical method (Delegate the call). 您不希望实际执行的每个真实调用都将其替换为模拟代码,而每次逗留都将调用真实连接对象的相同方法(删除该调用)。
In this way you are coding as usual, only differ in the returned object from the method that creates the connection. 这样,您像往常一样进行编码,只是返回的对象与创建连接的方法不同。
Now, in the mock object (your ConnectionImpl) you can add unit testing code that checks input, for example. 现在,在模拟对象(您的ConnectionImpl)中,您可以添加例如检查输入的单元测试代码。

If you're not concerned with how MyObjectWriter works, just that it does, then I would be inclined to write an integration test and forget about a unit test. 如果您不关心MyObjectWriter工作原理,而只是关心它的工作原理,那么我倾向于编写一个集成测试,而不必考虑单元测试。

You don't mention how you're testing the stored procedure, so forgive me, but what I would do is write tests around MyObjectWriter which invoke the actual stored-procedure on a database and then verify the database state afterwards. 您没有提到如何测试存储过程,所以请原谅我,但是我要做的是围绕MyObjectWriter编写测试,这些测试调用数据库上的实际存储过程,然后验证数据库状态。 I would use an in-memory database, if possible, to keep test durations down. 如果可能的话,我将使用内存数据库来降低测试时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM