I would be as defensive as you need to be. A bit ambiguous, I guess so but I will try to explain.
When you right a method, if that method has input parameters you have to make the decision on what you expect those parameters to be. In situations and places within an application this will differ. For example, if a method or piece of code is accepting data from a user input then you would want to cover all code basis and handle any input accordingly whether via an error message or some nice way of displaying unacceptable data.
If the method is an exposed API ditto. You can't control what is coming in so you should expect to try and cover all aspects and program accordingly.
For methods that are produced within the core engine of your project, here you have a decision to make. Do I assume the data that is arriving has been pre-screened and validated before it arrives or should I put in the necessary checks. I guess this depends on the conceptual level of the method and if this is an acceptable place to check. So things I might consider is:
1) Is this the only place I will need to do this check? Will this variable need to be checked in lots of different places for this condition. If so can I do the check once higher up the chain and then assume validity afterwards
2) Are other components of the system expected to work with the methods and interfaces I write. If so can you control through debug assert statements, debugging exceptions, method commenting and general system architecture the outcome you require, or will the data need checks put in place.
3) What are the outcomes of failure at this point in the code. Will it cause the entire thing to fail? Will any error be caught elsewhere and will that error at least be caught.
4) Does it make sense to put a check here? Sometimes putting a check on a piece of possible corrupt data although helping to solve the issue at that point and not error out might help cover it up. At which point you might spend hours chasing down a different issue only to find the actual issue was because of a valid check on data whay back in the chain of events that cascaded to the one the user/developer was reported.
In general I am a defensive programmer however I also believe that with thorough TDD and appropiate unit testing that you can put in the checks in code at the required levels and be confident that it is working as it should once it gets to any lower level sections.