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 busi
YMHO There is a bit of semantic issue and a bit of a technical issue here.
A unit test is supposed to test a small part of code, in isolation, to check it without other code. A failed Unit Test should imply that only a small part of code will have to be inspected corrected (tipically, the code implementing the functionality and the unit test itself).
Other scopes of testing exist to check functionality of the system as a whole (system test), or functional tests to validate complete features, or integration tests to check interactions, regression testing to check for the absence of already corrected test etc.
A testing strategy has to be devised for each project, but in general having different categories helps a lot. So unit tests should be restricted to testing the smallest possible units of code, and use other testing procedure to test functionality, integration etc.
The semantic part is whether is correct to use a unit test library to perform some functional test, I guess it is no biggy if you keep your suites separated the strict unit tests and the functional tests (even if they share the testing tool)
There are two main reasons for unit tests not hiting the 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.
Well, the thing is, if you have your unittests hit the database, you're not testing just the single unit of code, but instead you're hitting several - also the DAL, stored procedures, etc. Thats why TDD proponents say not to hit the database in unittests.
Its also why you shouldnt hold much weight in pure, TDD-conceptualized, theoretical holy Unit Tests. While unittesting is not a bad thing per se, and in fact is quite important to ensure the programmers build each component properly - system testing is way more important. Overall, it may be harder to find the exact method that caused system tests to fail, they're more realistic and actually test the system.
So-called "Component Testing" - which is more like system testing, but for only one small part of the system, end-to-end - seems to me to be a good compromise.
(Cue the TDD rebuttals now... :) )
After writing Should one test internal implementation, or only test public behaviour? and discussing people's answers, I think that the answer may depend on how many people are on the development team.
Advantages of testing with the database:
Disadvantages of testing with the database:
The disadvantages are especially important if (but perhaps only if) the person writing the upper layer isn't the same as the person writig the database access layer.
"...the database should not be hit when the unit tests run..." - unless you're unit testing persistence objects, of course.
I don't know which blogs you're citing, but I'll bet what they're saying is that mocking some components during integration testing can have benefits. If you've already unit tested the persistence tier, there's no need to test it again. The benefit of mocking in that case has more to do with reducing dependencies and uncertainty. For example, you might have unit tested your code, packaged it up, and now it's time to move it into an environment that's closer to production. If the databases you need can't be available (e.g., don't have the proper version of the schema, missing data that you need, or simply needed by another application that got there first), you can use mocks to allow your integration test to proceed without delay.
The problem in adressing the database in your tests is that a change in the database or a change in your code can fail the test. A unit test normally should point as direct as possible to the change that made him fail. So if you want to test the code for the DB access maybe use a fixed test database. In this way you are sure that the code that accesses the DB is wrong because you know the database hasn't changed and if you want to change the DB setup change the test DB first and see your test fail then fix him and then change the not test DB. In a project I worked in we created a small database that was generated into memory prior to each test.