What he said is, if you dont create tests first, refactoring is just changing shit. The behavior is supposed to be invariant across refactoring. The only way you can be sure is to test the before and after.
Won't it be nice when we have refactoring tools that are trusted enough such that you can remould code (even legacy code) without the pain of writing unit tests?
Moving from C to Java you really appreciate tools like IntelliJ and Eclipse which can automate some refactorings with a fairly high amount of certainty that it's not going to change the behaviour.
The safe refactorings included in IDEs have a far higher bar of safety than mere testing; if the code is syntactically correct and there are no escapes from the static type system used (such as reflection), then the refactorings are proven to be correct, no testing needed.
Reflection does not break the static type system in any way. However you are right in assuming the refactorings are in general not correct in the presence of reflection.
In fact, testing the software is not just there to make refactorings possible. The tests for the software are there to check if the software behaves correctly for a (hopefully representative) set of inputs.
Thus, the check if a refactoring is invariant is mostly a side effect from having a test suite for your software, and thus, in my opinion, it does not matter how secure your recfactorings are. I do have my tests already!
(And yes, I do consider it a heavy code smell if there are no tests written, because lots and lots of things are so very, very easy to test if structured ... if structured ok. not even well structured, just without hard-coded dependencies)
The thing is, I don't really like "tools" for refactoring, because they take me a little too far away from the code.
For example, they might make mistakes, like changing only the code references and not the comments; or be mildly annoying by screwing up indentation.
I feel better being forced to visit every line, to see the whole scope of the change and realize just what it's doing to the code. Occasionally, this has made me realize that the refactor is not even the right thing to do. Also, it is one of the few chances I have to force myself to read code that I don't visit often; it can result in me writing down a few other things to go back and fix later (a mini-code-review, basically).
When speaking with arab-speaking programmers, I find myself using the translation of words like "congruence" more often. It actually sounds better in arabic too:
Technically, we have this one too: identity, versus equivalence. Just like in the real world: when one thing can replace another (it has the same members or properties), they are equivalent; when modifying one would modify the other (or, if you like, when two of the same thing occupy the same space, e.g. the house at 123 Fake St. and the house at 123 Fake Street), they are identical. There's no need for the word "pointer" in that explanation, notice :)
"Equal", however, means neither equivalence nor identity; it's generally just a math term, meaning "identical/equivalent in magnitude" (where numbers are the only things for which "equivalence" is "identity.") Phrases like "equal rights" imply that the total value of the rights can be reduced to a number, and compared; to put it another way, that the rights are sortable. "Equal" has no meaning for things which cannot be sorted—there can be "equivalent paintings", or "identical paintings", but never "equal paintings."
"Equal" is basically the worst possible term to have absorbed for talking about the comparison of anything other than numbers. The underlying comparison is always one of either identity, or equivalence, and this should be simply stated outright—it causes no confusion, nor are there any special cases for which "equal" is necessary.
I don't know where you're getting this idea that equality only makes sense on numbers. In set theory for example, {a,b} equals {a} union {b}, we don't say it is "identical to" or "equivalent to", it IS the same thing. But we don't necessarily need to define an ordering on sets; the equality makes sense without the notion of sorting.
Aye, you've caught me. Let me rein myself in, then: equality makes sense for value objects only (as value objects have no sense of separate identity; for value objects A and B to be equivalent means that they're also a singular entity.)
That's still a minority of the objects we deal with in programming, though, and again, there's no reason to say "equals" when you can specify "is equivalent to" or "is identical to" instead; value objects will happily give you your expected answer under either comparison, and it will force you to define the comparison for business/model objects (that is, those with IDs) as well.
You'd also want to make sure you're getting some benefit from your refactoring activity. Are you winding up with less code? Is it more readable? Most important: are you getting closer to Don't Repeat Yourself?