1

I have a very specific situation in an integration test.

I'm developing a Rest API composed by few micro services using spring boot. Some of those services have basically crud operations to be accessed by an UI application or to be consumed into internal validations/queries.

All the database manipulation is done through procedures by a legacy library (no jpa) and I'm using a non-standard database. I know that the good practices say to do not use real databases, but in this scenario, I cannot imagine how to use a dummy databases in the test time (like dbunit or h2). In this way:

1 - Is it ok to hit the real database in an integration test?

If 1 is ok, I have another question:

Usually, we do not change the data state in unit/integration tests; and the tests should be independent of each other.

However, in my case, I only know what is the entity id in the response of the post method, making difficult to implement the get/put/delete methods. Of course in the get/put/delete methods I can first insert and then make the another operation, but in this perspective, at the end, I will have a database in a different state of the beginning of the test. In this way, my another question is:

2 - How can I recover the database to the same status before the tests?

I know that it could be a specific situation but I really appreciate any help to find an elegant way of testing this scenario.

Thanks in advance.

Matt M
  • 3,699
  • 5
  • 48
  • 76
pedrohreis
  • 1,030
  • 2
  • 14
  • 33
  • 1
    An integration test *would* hit a real database--because it's an *integration* test. There are many ways of seeding the database, e.g., DbUnit, but there are others. – Dave Newton Apr 08 '17 at 03:49
  • Just take a copy of the database with data and after finishing the integration test, use it – Fady Saad Apr 08 '17 at 03:51
  • Are you thinking of using live data? Could someone else be accessing the data while you're running your test? If you modify the database and someone else could be accessing your test data and think it's real data, what problems might that cause? – ajb Apr 08 '17 at 03:51
  • @DaveNewton, what are my other options? I'm using procedures of a non-standard database and I do not want to define the tables and procedures twice (one using the metalanguage of my db and another of my 'test db'). – pedrohreis Apr 08 '17 at 04:00
  • @user7790438, I'm in a continuous integration environment but a few builds in a day. I do not think that making backups and recovering every time is a real solution. – pedrohreis Apr 08 '17 at 04:01
  • @ajb, it is not a real problem in dev environments. However, in production, for example, I must be sure that I'm manipulating 'non-real' data and to recover the db to the initial state. – pedrohreis Apr 08 '17 at 04:01
  • 2
    Yes, I had the same situation, the best solution is to use a staging server with his own database just for testing – Fady Saad Apr 08 '17 at 04:02
  • Try the in memory database H2. It is handy for this sort of testing. You get to always start with the same database content. – Jason K. Apr 08 '17 at 04:05
  • Seems like you need to stand up another instance of the DB and seed it. I can't recommend against testing in the production database strongly enough unless it has an explicit mechanism or was designed with that usage in mind. – Dave Newton Apr 08 '17 at 04:49

3 Answers3

3

You should ask differently: is the risk acceptable to run tests against your production db?

Meaning: if your tests only uncover problems in your code, everybody will be happy.

But if you mess up and the database gets seriously corrupted, and the whole site needs to be taken down for a backup that fails initially... So your business goes offline for 2 days, how do you think your manager will like that?

Long story short: it depends. If you can contain the risks- yes sure. But if not, look for other alternatives. At least : make sure that your manager understands what you are doing.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Frankly, I'm not excited about run those test on a production environment, since you always must assume the risks for all 'productions tests'. Ideally, they shouldn't break all the database (it's only a few crud operations) but in my mind is better to recover the database to the initial state. Not sure, but configure an integration environment could be an alternative to avoid run against production. Anyway, I'm prospecting alternatives since this kind os testing in very easier when using jpa where you can mock a data source in dummy database. – pedrohreis Apr 08 '17 at 04:59
1

Integration test are fine and a must I would say as long as you don't run them in a production environment. It allows to test the overall application and how you are handling responses, serializations, and deserializations. Your test cases should handle what you expect to have in you production database and every test test should be isolated and what you create in your test case you must delete it after it so returning to its original state, otherwise you might have clashing test cases. Test integration tests in a local database or a dedicated testing database.

Juan M
  • 11
  • 1
0

You can specify the in memory H2 database for interface integration testing and populate it as needed for specific tests. This is useful when you are running in situations where having a database on your Jenkins or similar unit test system doesn't make sense. It really depends what you are testing ie end to end integration or finer grain integration.

Jason K.
  • 790
  • 1
  • 14
  • 22
  • Not sure if I was clear. But in my situation, it's not so simple to use an in-memory database like h2 to make the test. 1 - I'm not using a standard database (what means that the db's metalanguage is not completely following the ansi sql.), and it is ok to have 2 definitions for each table and procedure; 2 - I'm not using jpa and my 'db library' it only prepared to query the target database through procedures. – pedrohreis Apr 08 '17 at 04:05
  • Mockito is another option but is more unit test focused. It can work in situations like this as well. – Jason K. Apr 08 '17 at 04:07
  • I need to test my procedures call. All the application is designed to use this approach. Mockito and dbunit/h2 are very cool when you can just mock the results. It isn't my case, I need to make a point to point validation. – pedrohreis Apr 08 '17 at 04:09
  • In that case, you probably have to keep a separate database running that you truncate and populate before running your test suite. – Jason K. Apr 08 '17 at 04:15