I\'ve this confusion all the time. If I write a code which uses fake code to assert some operation, how do i trust my real implementation when it is started really using the
Most kinds of unit testing is about testing individual pieces of code, and stubs and mocks are simply tools that assist you in testing piece-by-piece. By testing pieces individually you can probably test each piece in greater detail, but you will not be guaranteed anything about the full picture. Various kinds of integration testing will do that.
When testing bigger pieces of functionality, I often find actual integration tests of database logic to be the least valuable test artifacts, since you will often be testing these same operations at the UI level.
Martin Fowler has a good discussion here.
From his article:
Meszaros uses the term Test Double as the generic term for any kind of pretend object used in place of a real object for testing purposes. The name comes from the notion of a Stunt Double in movies. (One of his aims was to avoid using any name that was already widely used.) Meszaros then defined four particular kinds of double:
Of these kinds of doubles, only mocks insist upon behavior verification.
You use stubs when you just want a function to return some value (or do nothing). You don't really care if the function was called or not, you just want to isolate things.
Mocks are more powerful, as you can also keep track if the function was called, how many times, and even do things with values your function gets.
In your case, if you want to mock the database (so it becomes a unit test rather than a functional one), you can mock ISession and ITransaction. You could then store this values in-memory, and check if the correct values were saved.
You should be testing the code that you have written. If you wrote the database connection object code, then test it. Otherwise if it is part of a library with it's own tests, you can just mock/stub it and assume that if the connection object passes it's own test suite, then it works.
For example, I wouldn't test calls to Hibernate methods, I assume the Hibernate developers have thoroughly tested that already. But I would test that I was calling the correct method, using a mock to set up that expectation.
Yes, using a real database would be more functional or integration testing, depending on your definition. Personally, I feel that unit tests are supposed to test exactly that method only, in isolation of everything else. So regardless of whether the session or the transaction works or not, your unit test must ensure that those objects will be called upon to do their work when and as necessary - that's where mocks and stubs come in. You use them to ensure that your unit test is as decoupled from external functionality so that it can be tested as a basic unit; ideally anyway.