Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad practice to allow my Junit tests to interact with a real DB?

Tags:

java

junit

flyway

I'm building a basic HTTP API and some actions like POST /users create a new user record in the database.

I understand that I could mock these calls, but at some level I'm wondering if it's easier to let my Junit tests run against a real (test) database? Is this a bad practice? Should only integration tests run against a real DB?

I'm using flyway to maintain my test schema and maven for my build, so I can have it recreate the test DB with the proper schema on each build. But I'm also worried that I'd need some additional overhead to maintain/clean the state of the database between each test, and I'm not sure if there's a good way to do that.

like image 299
user2490003 Avatar asked Aug 23 '18 06:08

user2490003


People also ask

Should unit tests connect to the database?

Unit tests shouldn't depend on infrastructure There's no way to test this function without having a database connection available at the time of testing. If a new developer clones the project they will need to set up a database or else tests will fail.

Should you mock a database?

The best solution is to virtualise and parallelise your isolated integration tests against a well-known data set. It runs more slowly, but you'll spend much less time setting this up correctly, fixing bugs that are due to bad mocking or bad emulation. Conclusion: Stop mocking your database.

Does integration test use real database?

In the context of applications using a database, integration tests usually require a database to be available and contain data that is convenient to the scenarios intended to be tested. One way to simulate a real world environment is to use Docker to encapsulate a database and some test data.


Video Answer


2 Answers

Unit tests are used to test single unit of code. This means that you write a unit test by writing something that tests a method only. If there are external dependencies then you mock them instead of actually calling and using those dependencies.

So, if you write code and it interacts with the real database, then it is not a unit test. Say, for some reason your call to db fails then unit test will also fail. Success or failure of your unit test should not be dependent on the external dependencies like db in your case. You have to assume that db call is successful and then hard code the data using some mocking framework(Mockito) and then test your method using that data.

like image 154
Yug Singh Avatar answered Oct 01 '22 03:10

Yug Singh


As often, it depends.

On big projects with lots of JUnit tests, the overhead for the performance can be a point. Also the work time needed for the setup of the test data within the database as well as the needed concept for your tests not interfering with the test data of other tests while parallel execution of JUnit tests is a very big argument for only testing against a database if needed and otherwise mock it away.

On small projects this problems may be easier to handle so that you can always use a database but I personally wouldn't do that even on small projects.

like image 44
Niklas P Avatar answered Oct 01 '22 01:10

Niklas P