- Easily extendable(meaning a class can implement multiple interfaces etc..).
- Standard contracts. You have the common methods in the interface. And different Classes can implement the logic in their own way. The client calls the class that is applicable.
It all is beautiful, Agreed. But nonetheless the actual beauty of using an interface lies in the fact that TDD(Test Driven Development) becomes bloody easy. Everything falls nicely into place.
Many developers don't really understand what unit-testing is all about. They write some obviously passing unit tests and that's that. Not much effort really goes into writing good unit-tests. Well, you can't always blame the guy who is coding. There are many hidden implications here.
First of all, if he is writing some new code which is using many other existing classes(utility classes or core business specific classes or anything for that matter), its not always possible to unit-test his new code. Reason - The old classes were written without the "testable" approach in mind. Secondly, if this new code has some Database calls or Web Service calls, then its tricky to write unit tests (or at least that seems to be the myth out in the wild!). So, the guy goes.."Nahh..Forget it. Its hard. Am sure my code works OK. No need to unit-test. Unnecessary effort"
In the first case - you should have followed the TDD approach when you wrote the old classes to begin with. Try to refactor the code into what I call the 'Testable Interface' design.
In the second case - IT IS POSSIBLE. You just have to mock the DB calls and put the web service calls behind an interface. Again Testable Interface Design.
Testable Interface Design:
If you have to write a class to do,
- Call a web service and get some output A.
- Process that output(some business logic) into an output B.
- Write B to the database.
If I ask developers to unit test this, many would write some code which tests the whole process end - end, all the 3 steps. But technically our job is to test ONLY step 2. The web service call is external to your code, so you can't control it. So you shouldn't write a test that depends on the output A. And coming to the Database call, you shouldn't write a test which actually writes stuff into a test database. That writing might fail if there is a bug in the Stored Procedure, which is again not your problem, I mean not your code's problem.
So just test Step 2 - business logic. But how? If you write a test which calls the method, it goes through all the 3 steps. How to manipulate the functionality of that method, so that it only does Step 2. That's where Mocking comes in. The most cutest thing I laid my eyes on since Meg Ryan!
You just have to mock the output of the webservice and the database and just test your business logic. Hmmm sounds nice, but what's mocking. Mocking is nothing but making the objects return what you want. So if you can find a way to make the webservice(obj 1) and the database(obj 2) to return some output, your problem is solved.
First put both the client code that calls the WebService and the code that writes stuff to the database in an INTERFACE.
Implement its logic in a class,
And write your main code like this,(Please click on it to view clearly)
So your test code goes something like this (am using the Moq library - very simple to use)
See......Simple eh! :)