Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not hit the database inside unit tests?

I've read in blogs that the database should not be hit when the unit tests run. I understand the theory, however say i have complex store procedures that are part of a business domain operation. I want to write a set of unit tests for the code related to the business operation, however if i mock the database i have the feeling that im not "really" testing all the parts that are part of the operation. For example someone could create a bug in one of the database code and the tests will still be running ok.

I would like to know if this guideline about unit tests is good in practice. I've seen the concept of "integration tests" however im not sure about what tools to use to do integration tests. For example ¿Is it ok to create an integration test using a test framework like Nunit?

Thanks

Hugo

like image 285
Hugo Zapata Avatar asked Jun 28 '09 14:06

Hugo Zapata


2 Answers

You are simply in a semantic grey area.

  • System tests cover the whole system from end-to-end.
  • Unit tests can be used to describe a sub-segment of the end-to-end cycle.

In that case your unit tests of your application code would/might not hit the database, but you would/might have unit tests that covered your database stored procedures...

Basically divide your application into things to be tested along partitions that make sense. If you choose the wrong partition line you end up with a big code maintenance problem with mock objects and test scaffolding and stuff...

A common way with web apps is to write a series of unit tests that test the data access layer...

Then write a series of unit tests that test the application layer (including the data layer) ...

And finally write some browser-based system tests...

The trick is to only put information in and out of the middle set - the application layer - through the API and not burrow into the database to see if something worked. That way your tests won't break if you change the data schema.

But sometimes (as I actually currently doing as I write this) you HAVE to look into the database to make a meaningful and robust test suite (I am testing server-server transfer protocols).

Focus on the way that gets maximum code coverage and stability for your application, whilst writing the least amount of testing scaffolding, and avoiding brittleness in your test suite.

like image 66
Gordon Guthrie Avatar answered Oct 07 '22 14:10

Gordon Guthrie


There are two main reasons for unit tests not hiting the database:

  • You want your tests to go as fast as possible
  • You want to test your code as a single unit, not how it integrates with other code/ database.

In your case you need to test the stored procedures. Then you need to write a test that runs those stored procedures. Either you can run them via your code (Integration test) or you can run them directly from the test (sort of a unit test). In both cases you can use Nunit.

like image 37
Shiraz Bhaiji Avatar answered Oct 07 '22 14:10

Shiraz Bhaiji