Testing JDBC methods, including transactional aspect and connection closeds - java

I would like to define tests for JDBC methods for educational purposes. In particular, in addition to test whether the JDBC methods have the functionality required (I have seen that there are solutions such as DBUnit, etc), I would also like to check whether the methods verify specific requirements:
- if they consider transactional issues when modifying (setAutocommit(false)/commit/rollback)
- if they close the connection,
- etc.
I have not found any testing solution that checks whether spectific methods are invoked (methods such as the previous ones). The only thing that comes to my mind is trying to use a testing solution (such as DBUnit) together with AOP (for example AspectJ) for advising whether such methods are invoked.
Any other idea?
Thank you!

There are mainly three ways to do what you want to achieve:
Mocking JDBC
Popular choices are mockito or jmock. Using jmock, for instance, you can write things like:
Mockery m = new Mockery();
Connection c = m.mock(Connection.class);
PreparedStatement s = m.mock(PreparedStatement.class);
m.checking(new Expectations() {{
oneOf(connection).prepareStatement("test"); will(returnValue(s));
oneOf(s).setFetchSize(10);
oneOf(s).execute();
oneOf(s).getUpdateCount();
oneOf(s).getWarnings();
oneOf(s).close();
}});
And then:
// Example code under test:
try (PreparedStatement ps = c.prepareStatement("test")) {
ps.setFetchSize(10);
ps.execute();
ps.getUpdateCount();
ps.getWarnings();
}
// Finally, check if everything was called as expected.
m.assertIsSatisfied();
Implementing JDBC
Mocking APIs help you provide a mock implementation very easily, but you may wish to do much more than just mock the driver. In that case, you could actually implement JDBC:
class MyConnection implements Connection {
final Connection delegate;
public MyConnection(Connection delegate) {
this.delegate = delegate;
}
// ...
}
In this case, you can now intercept any method call and start collecting statistics and make assertions inside of the desired methods without modifying the underlying database interaction, as all JDBC calls will be delegated to the actual driver.
Many libraries, including e.g. jOOQ, ship with utilities for creating such proxying JDBC objects, see e.g. jOOQ's DefaultConnection. jOOQ also has an entire mock JDBC implementation, which can be seen in these articles:
https://blog.jooq.org/2018/04/10/mocking-jdbc-using-a-set-of-sql-string-result-pairs/
https://blog.jooq.org/2013/02/20/easy-mocking-of-your-database/
But I'm not sure if that's what you're after.
(Disclaimer: I work for the company behind jOOQ)
Using AOP
By using a tool like Javassist, you can intercept certain method calls such as the desired JDBC method calls, and run additional logic before or after the actual call. This works in the same way as the previous approach of implementing JDBC, except you don't have to modify the application under test, so it is the least intrusive and simplest approach for simple validation tasks.

Related

Reusing same #Transactional method for different DataSources (JdbcTemplate) in Spring

we have this code where the same service method will call different daos each using a different datasource (and different JdbcTemplates). We would like to use #Transactional annotation, but as far as I know, this annotation is always linked to a specific TransactionManager (and thus, to a specific DataSource).
So, my question is, is there a way to choose dynamically which DataSource (or TransactionManager) using when calling a #Transactional method so I can reuse that method to attack different databases?
The #Transactional annotation doesn't allow dynamic evaluation of the value attribute which selects the TransactionManager (possibly by design, at least it doesn't look like it's going to change any time soon). So you can't have something like #Transactional("#{#getTxManager}") which would resolve the tx manager at call time.
In simple cases you might be able to get away with the following, but it would only be worth considering when for example you have a primary DS, and a secondary DS that's used only in some cases. Otherwise you'd be peppering the code that selects between calling foo/bar all around, and that wouldn't look clean at all
// TX boundary on the "top" abstraction layer
#Transactional("foo")
public void foo() {
doWork();
}
#Transactional("bar")
public void bar() {
doWork();
}
private void doWork() {
// Work done here, no concern for tx management
}
For more complex cases like multitenancy, AbstractRoutingDataSource is an easy and robust choice if you haven't considered it yet. Although depending on how much switching you need, it may require tweaking or be even unsuitable.
Finally, you might be able to create your own annotation that does choose the DS dynamically (although I don't guarantee it), but that would be the riskiest approach for possible very little gains.
The safest way for you would be to create separate services for each dao... I wouldn't like to be debugging such code. Think about maintaining this code and possible failures that might happen.
If I were you I'd ask myself following questions:
1.) Why separate dbs?
2.) Isn't the context somehow mixed up? Maybe create some boundaries between them?
3.) Do my queries really need to be transactional?
I probably don't know the context of your problem but for me it seems that you've modeled your application in a wrong way and I'd focus on it.

What is the difference between full mocking and partial mocking?

I'm currently working with mocking with Mockito using jUnit and I've stumbled upon the Partial Mocking section where you use Mockito.spy to partially mock the object. I don't seem to understand this concept of partial mocking since I can't find a scenario why I should use it (since it's pretty similar to mocking in general).
Can anybody explain how partial mocking differs from the normal mocking? And if possible, kindly provide examples.
Thanks!
Partial mocking is where you take a class and ask it to behave as normal, except you want to override certain functionality.
This is useful for unit testing services who communicate with other parts of your application. By overriding the behaviour that would call the other part of your application you can test your service in isolation.
Another example would be when a component would communicate with a database driver. By mocking the part that would communicate with the driver, you can test that part of the application without having to have a database.
From the EasyMock 2.2 classextension documentation:
Sometimes you may need to mock only some methods of a class and keep
the normal behavior of others. This usually happens when you want to
test a method that calls some others in the same class. So you want to
keep the normal behavior of the tested method and mock the others.
I sometimes use this to mock (complicated or process intensive) private methods that are allready fully tested.
Partial mocking can be very handy, but I try to avoid it as much as possible.
Partial mocking:
Say you have a class which takes 10+ parameters for a constructor (this shouldn't ever happen but for this example lets say it does) it's a real chore to create that entire object. Frameworks like mockito let you just use the parts of the object you really want to test.
for example
#Mock BigClass big; //contains loads of attributes
...
when(big.getAttributeOneOfTwenty()).thenReturn(2); //these are static imports from mockito
I find it useful when I'm forced to work with APIs relying on inheritance from abstract classes and/or legacy code working with nonmockable static classes (one real life example - DAO).
Partial mocking (in sense of using the Spy facility from Mockito) allows you to mock calls to inherited methods in the first case, or wrap calls to static methods you are forced to use into normal methods that you can mock, verify etc.
Generally you should design and write code in such a way, that you won't need this (dependency injection, single responsibility per class etc). But from time to time it's useful.
A quick and rough example, to visualize the static API example:
class BigUglyStaticLegacyApi {
public static Foo someStaticMethodFetchingFoo() {...}
}
class Bar {
public void someMethodYouTest() {
Foo foo = getFoo();
//do something with Foo (a FooBar, for example :) )
}
/*this one you mock via spying - not the most elegant solution,
but it's better than nothing */
#VisibleForTesting
protected Foo getFoo() {
return BigUglyStaticLegacyApi.someStaticMethodFetchingFoo();
}
}
I use it the most to mock some methods in my CUT (Class Under Test) but not the method/s I'm actually unit testing. It is an important feature that should be used in unit testing with Mockito.

How to test "add" in DAO without using "find" etc.?

In following code the issue is, that I cannot test dao.add() without using dao.list().size() and vice versa.
Is this approach normal or incorrect? If incorrect, how can it be improved?
public class ItemDaoTest {
// dao to test
#Autowired private ItemDao dao;
#Test
public void testAdd() {
// issue -> testing ADD but using LIST
int oldSize = dao.list().size();
dao.add(new Item("stuff"));
assertTrue (oldSize < dao.list().size());
}
#Test
public void testFind() {
// issue -> testing FIND but using ADD
Item item = new Item("stuff")
dao.add(item);
assertEquals(item, dao.find(item.getId()));
}
}
I think your test are valid integration tests as stated above, but I would use Add to aid in the testing of of Find and vice verse..
At some level you have to allow yourself to place trust in your lowest level of integration to your external dependency. I realize there is a dependency to other methods in your tests, but I find that Add and Find methods are "low level" methods that are very easy to verify.
They essentially test each other as they are basically inverse methods.
Add can easily build preconditions for find
Find can verify that an add was successful.
I can't think of a scenario where a failure in either wouldn't be caught by your test
Your testAdd method has a problem: it depends on the assumption that ItemDao.list functions properly, and yet ItemDao is the Class that you're testing. Unit tests are meant to be independent, so a better approach is use plain JDBC -as #Amir said- to verify if the record was introduced in the database.
If you're using Spring, you can relay on AbstractTransactionalDataSourceSpringContextTests to access JDBCTemplate facilities and assure a rollback after the test was executed.
I use direct JDBC (using Spring's JdbcTemplate) to test the DAO methods. I mean I call the DAO methods (which are Hibernate base), and then confirm them using JDBC direct SQL calls.
The smallest unit under test for class-based unit testing is a class.
To see why, consider that you could, in theory, test each method of the class in isolation from all other methods by bypassing, stubbing or mocking them. Some tools may not support that; this is theory not practice, assume they do.
Even so, doing things that way would be a bad idea. The specification of an individual function by itself will vary between vaguely meaningless and verbosely incomprehensible. Only in the pattern of interaction between different functions will there exist a specification simpler than the code that you can profitably use to test it.
If you add an item and the number of items reported increases, things are working. If there is some way things could not be working, but nevertheless all the patterns of interaction hold, then you are missing some needed test.

AOP for third-party classes

I have used AOP within spring with no real problems, mainly for transaction management, for which it works a charm.
My question is this... the only examples I've seen for AOP so far is to pointcut a class that you have created yourself. Is it possible to pointcut a class within a third party library, for example a database connection class. The context is that I wish to create some logs and gather information when an oracle data source executes a call to the database, which is unfortunately contained within a stack of oracle class files. How would you pointcut this class/method when the SQL is executed?
I think this will work:
Let Spring be responsible for initializing your DataSource
Apply an aspect against the getConnection() method on your DataSource
In your advice, wrap the returned Connection in a new class ("LoggingConnection") which implements Connection and delegates all methods to the "real" wrapped Connection (I believe this is the Decorator pattern)
Add whatever logging code you need to the "LoggingConnection" class
Bear in mind that this approach creates a proxy of the original DataSource and delegates to it for each method call. In the context of a database operation this shouldn't create a lot of additional overhead. You will want to be extremely careful what your code is doing, lest it throw exceptions and prevent Connections from behaving appropriately. Perhaps use try/catch/finally and put the call that delegates to the "real" Connection in your finally block.
Another totally different approach would be to use AspectJ and do load-time weaving. That way you can decorate the class with new functionality as soon as the ClassLoader loads it.

How to mock classes instantiated as local variables

I'm writing tests for a business method that invokes some DAO classes to perform operations over a database.
This method, firstly retrieves a JDBC connection from a DataSource object, The same connection is passed to all DAO instances, so I can use it to control the transaction. So, if everything works properly, I must invoke commit() over the connection object.
I would like to test if the commit() is invoked, so I've thought to create an expectation (I'm using JMock) that checks that. But since the Connection class isn't a direct neighbour from my Business class, I don't know how to do this.
Someone knows how to overcome this? There is some JMock facility for this, or some alternative design that allows to overcome this?
Thanks
You need to mock DataSource and Connection so that your mock DataSource returns your mock Connection. And yes, this kind of thing ends up becoming a real pain...
It's hard for me to tell from your description exactly how your classes are composed, but the DataSource should be injected into your DAO class, either thru it's constructor or a setDataSource() method.
This would allow you to test the DAO in isolation, and allow you to construct the mock DataSource in your unit test and pass it to the DAO being tested.
Refactor so that the Connection is injected into the Dao and the Dao injected into the business class. You can then mock the Dao and / or the Connection. You can easily write your own mock that extends the Connection and overrides connect() to set a boolean that you later retrieve via a method that write such as wasConnectCalled().
I would definitely recommend that you use spring-jdbc instead of trying to write this kind of code yourself. This will make sure that the connection, statement and resultset are closed correctly. Spring also has excellent transaction management so you simply don't have to worry about this.
For example take a look at this typical update statement using spring-jdbc:
public void updateName(int id, String name) {
getJdbcTemplate().update(
"update mytable set name = ? where id = ?",
new Object[] {name, new Integer(id)});
}
Make the bussines class retrieve the local variables from a global/static object factory. That way you could put the factory in test mode and make it return mock objects instead of real ones.
That should make it.
#Paul seconded. And once you've split management of the connection out, you can write the rest of the behaviour in a callback that you pass into the thing that owns the connection -- like a UnitOfWork. The connection owner handles the transaction around, and passes the connection to, the UnitOfWork. Transactions in one place -- easy to test, UnitOfWork in another place, tested with a mock connection.

Categories

Resources