This is me going right back to basics with TDD for learning purposes.
I originally implemented Person.Surname as field of type object (the simplest possible way of passing the test.
I then added a test setting Person.Surname stating that the return value should be a string and set Person.Surname=20.
I ‘fixed’ the test by changing the implementation to use string rather than object. The test now long compiles due to static type checking, so I commented it out.
Person.Surname field is currently implemented as a string. If I change the implementation of the field to an object, none of my tests fail.
So I’m left with no way of leaving my intention in the test. Is there a way of having a failing test in this circumstance?
Update:
I agree with Esko, that practically this isn’t something you want to be doing.
From a learning point of view, the point I was trying to make was that if I (or someone else at a later point in time) widens the type scope of my field (say from string to object) I won’t have any directly failing unit tests. Maybe this isn’t a bad thing afterall?
Writing tests about a field having some type, is too low abstraction level. Write tests which describe features. Then the tests will better describe why the code was written, and you will be able to more freely refactor the implementation without breaking/invalidating existing tests.
When refactoring the production code, every now and then it will affect also the test code and you need to update the tests to make them compile and pass (the test code requires refactoring the same as all other code). When that happens, it’s helpful that the name of the test tells that what was the intention behind the test – what feature/behaviour is being specified by the test. Then you can update the test code so that the same intention remains. Or if the reason for writing the tests is no longer valid, then you can remove the test.