Database unit testing (MySQL) - java

I am trying to find a way to unit test my MySQL dependant code. I know how I would like it to work but cannot find the solution that would work for me. I have looked into DBUnit, but it would seem (if I am not mistaken) that this would require a running database and just aids with the unit testing side of things. I would like some way to avoid running a mysql database when testing. What would work great would be some sort of MySQL spoof driver that actually stored data in memory, rather than needing to access a real persistent database.
In my code it is hard coded to access a MySQL database so I can't just inject some mock object. The way I would like it to work is that when my code calls:
DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
It actually gets some other local database that can either be configured via maven or in the setUp of the maven test. I have looked into memory based databases such as HSQLDB but can't find a way for it to spoof the MySQL driver.
Are there any tools that provide what I am looking for? Do you have any good methods for testing MySQL dependant code?

I have had several projects in which I had to do integrations test against a running MySql server. Instead of spending time setting it up every time, I developed a library that sets up a local running instance of MySQL every time you run your tests.
With that you get a test database that acts like the real thing (because it is) without having to set it up.
DBUnit is also a good alternative if you want to mock the database integration (as far as I know, there is no need for a real MySql server when using DBUnit).

Related

Mock Database, MockMvc

I have a simple REST app with MySQL database, everything works fine, but while testing do we need to create a dummy object and test on it, or test via Mock database?
The dummy object has quite large constructor and nested classes, which is a lot of work.
IMO, there's little point using a mock database, unless you're testing connectivity handling. For example, how does my application behave if the database connection is dropped etc.
For testing SQL, you will do no better than testing against the actual database you're going to use in production. If you use another database as a substitute, i.e. H2, make sure you understand that you are testing a DB driver and database that will be different to your production deployment and this means that you may not catch potential errors in your tests that use this setup.
For testing data handling, you could also use a mock of some kind but again, if you're always going to be better off using the actual database you will be using in production, whenever you can.
If you're using Hibernate as an ORM provider, as part of setting up your integration tests, you can have it execute DML scripts to load your data for testing purposes.
If you using spring boot, then H2 is one of the popular in memory databases. Spring Boot has very good integration for H2.
For integration tests, you should consider using a database in-memory, such as H2.
H2 supports compatibility modes for IBM DB2, Apache Derby, HSQLDB, Microsoft SQL Server, MySQL, Oracle and PostgreSQL. To use the MySQL mode, use the database URL as shown below (and refer to the documentation for further details):
jdbc:h2:~/test;MODE=MySQL;DATABASE_TO_LOWER=TRUE

Unit testing DAO layer with H2 database

After a lot of reading in internet, i found out that it seems to be a good practice to use a in-memory DB like H2 to unit test the DAO layer. The idea behind is to avoid working with the production DB.
Fine, so I set up a H2 DB and activated the H2 PostgreSQL Compatibility Mode, since my production DB is on Postgres. The problem I'm now facing: when I run on H2 the original SQL queries in order to build the test DB, this query is not accepted as valid by H2:
ALTER SEQUENCE MYERP.ecriture_comptable_id_seq OWNED BY MYERP.ecriture_comptable.id;
I guess that using the PostgreSQL Compatibility Mode is not a guarantee that all the Postgres specific syntax will be accepted by H2. And probably this would also happen with other DB such as MySQL.
So what's the point in using a h2 database in this case?
Did I miss something?
Unit testing should focus on testing a unit. PostgreSQL is external to your application and thus trivially not part of any DAO that uses it: no 'unit test' should be written that uses any such external database.
Using the database for integration tests may be fine but as you already noticed multiple problems may arise when you use a different database to execute your integration tests (I know very little applications that only use ANSI-SQL without any triggers or other vendor specific SQL extensions like UPSERT in PostgreSQLs case or the SQL in your post).
So what if your production base is in-memory too? That's quite difficult and I would argue an integration test would be fine, just don't call it unit test. All of this just highlights the pain points of doing business logic in your database (e.g. through triggers that you now can't test) or using vendor specific sql which has several advantages that don't play so well with changing the underlying database vendor.

How to access MySQL database in jBoss BPM suite process

I am newbie in JBoss BPM Suite. What i want to achieve, is to access my MySQL database through a business process. I have already added a datasource to my application server including the jdbc driver. What i tried to do was to connect to my db by a script task. Although i got an exception ClassNameNotFound for my driver class 'com.mysql.jdbc.Driver'. What is the right way to connect to the db? Is there a way to do this by a service task? Or a WorkItemHandler?
Thanks in advance.
It is not recommended to execute any complicated logic (like accessing the database) in a script task. I would also assume that your application server does not put database drivers on the classpath of its applications since it is against the whole idea of datasources. You just need to make use of the datasource you have already configured.
When it comes to the right way how to connect to the database inside your process, you will need to implement your own work item handler where you can get your data from the database. There are many different ways how you can achieve this. You can find inspiration from JPAWorkItemHandler which will be available in version 7.
I have finally made the connection to my database by creating a WorkItemHandler and add it as a dependency to my BPM Suite project. After a lot of search, i think this is the best way to do it if anyone wants to access his database in a business process.

Mocking a database for system testing

I've read the following posts:
Is there a way to run MySQL in-memory for JUnit test cases?
Stubbing / mocking a database in .Net
SQL server stub for java
They seem to address unit/component level testing (or have no answers), but I'm doing system testing of an application which has few test hooks. I have a RESTful web service backed by a database with JPA. I'm using NUnit to run tests against the API, but those tests often need complex data setup and teardown. To reduce the cost of doing this within a test via API calls, I would like to create (ideally in memory) databases which can be connected to via a DB provider using a connection string. The idea would be to have a test resource management service which builds databases of specific types, allowing a test to re-point the SUT to a new database with the expected data when it starts - one which can simply be dropped on teardown.
Is there a way, using Oracle or MSSQL, to create a database in memory (could be something as simple as a C# DataSet) which the web server can talk to as if it were a production database? Quick/cheap creation and disposal would be as good as in memory, to be honest.
I feel like this is a question that should have an answer already, but can't find it/ don't understand enough to know that I've found it.

How to trace the connection pool in a Java Web application - DBMS_APPLICATION_INFO

I need improve the traceability in a Web Application that usually run on fixed db user. The DBA should have a fast access for the information about the heavy users that are degrading the database.
5 years ago, I implemented a .NET ORM engine which makes a log of user and the server using the DBMS_APPLICATION_INFO package. Using a wrapper above the connection manager with the following code:
DBMS_APPLICATION_INFO.SET_MODULE('" + User + " - " + appServerMachine + "','');
Each time that a connection get a connection from the pool, the package is executed to log the information in the V$SESSION.
Has anyone discover or implemented a solution for this problem using the Toplink or Hibernate? Is there a default implementation for this problem?
I found here a solutions as I implemented 5 years ago, but I'd like to know with anyone have a better solution and integrated with the ORM.
using DBMS_APPLICATION_INFO with Jboss
My application is above Spring, the DAO are implemented with JPA (using hibernate) and actually running directly in Tomcat, with plans to (next year) migrate to SAP Netwevare Application Server.
Thanks.
In Oracle 10g we can use DBMS_SESSION.SET_IDENTIFIER to uniquely identify a specific session. Oracle also provide a JDBC built-in to hook this into a connection pool. You will have to provide your own means of uniquely identifying a session, which will depend on your application.
Your DBA will then have enough information to identify the resource hungry session.
No DBA I know would be impressed with a huge text file generated from the middle tier.
If you want to know about queries that are costing a lot to run, you should go directly into your database server. There are monitoring tools for that, specific to each server. For example in PostgreSQL you would run SELECT * FROM pg_stat_activity as an admin to check each connection and what it's doing, how long it's been running, etc.
If you really want to/need to do it from the container, then maybe you can define an interceptor with Spring AOP to execute that statement you need before doing anything. Keep in mind that a database connection is not always used by the same application user, since you're using a pool.
You should be able to configure a logger (eg log4j) on your connection pool. You may need a custom appender to pull back the user ID.
Two points to consider:
On a busy system this will generate a big log file.
Frequent connections are not necessary an indication of behaviour that would degrade the DB.

Categories