tags:

views:

87

answers:

4

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.

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?

A: 

Couldn't you add a check like:

Assert.AreEqual( typeof(string), Person.Surname.GetType() );
Thomas
A: 

you can use the is operator....

if ( Person.Surname is string )
{
    // do stuff
}

you can also use as operator...

string surname = Person.Surname as string;
if ( surname != null ) // as succeded
{
    // do stuff
}
Muad'Dib
+1  A: 
Assert.IsInstanceOfType(Person.Surname, typeof(string));
John Buchanan
If the field is implemented as a string then this will obviously always pass.If the field is implemented as a object then this will still pass if a string is stored in the field (because string inherits from object).If you write a test initialising Surname to an int, when the member is implemented as a object then the test will fail. However once you fix the test by changing the type of the field to string, the test will no longer compile due to type checking.
AndyM
+5  A: 

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.

Esko Luontola