DevOps Zone is brought to you in partnership with:

Dror Helper is an experienced software developer has written and designed software in various fields including video streaming, eCommerce, performance optimization and unit testing tools. He is passionate about programming best practices and all things software development, and has been a guest presenter at several user group meetings and ALT.NET events. Dror's blog can be found at http://blog.drorhelper.com where he writes about unit testing, agile methodologies, development tools, programming languages and anything else he finds interesting. Dror is a DZone MVB and is not an employee of DZone and has posted 55 posts at DZone. You can read more from them at their website. View Full User Profile

How to return default(Type) in runtime – a TDD example in four unit tests

07.18.2011
| 7364 views |
  • submit to reddit

I’ve found this question while going over my old StackOverflow answers:

I'm using reflection to loop through a Type's properties and set certain types to their default. Now, I could do a switch on the type and set the default(Type) explicitly, but I'd rather do it in one line. Is there a programmatic equivalent of default?

I encourage you to read till the end before checking my answer – because I want to show you how this task can be solved using TDD (Test Driven Design).

Test-driven development.PNG

[From Wikipedia]

 

Test #1 – handle null input

Let’s write the first test – when null is passed return null:

[Test]
public void GetDefault_PassNull_ReturnNull()
{
    var result = DefaultCreator.GetDefault(null);
 
    Assert.That(result, Is.Null);
}

Now all we need is to make the test pass and so implementing this requirement is as simple as can be:

public class DefaultCreator
{
    public static object GetDefault(Type type);
    {
        return null;
    }
}

Although this seems like cheating this is the way to create the design piece but piece, instead of creating it all upfront I hope that things would get clearer in the process just keep in mind that the worse case scenario is that we have a test that checks what happens if null is passed.

Test #2 – reference types

Next test - if T is an object default(T) will return null:

[Test]
public void GetDefault_PassObject_ReturnNull()
{
    var result = DefaultCreator.GetDefault(typeof(object));
 
    Assert.That(result, Is.Null);
}

Running the test shows a cool feature of test driven design – the test passes! and so right now we have a class that satisfies two out of three of our requirements.


Test #3 – primitives

All we need to implement now is how to behave when a value type is passed – and so we write another test:

[Test]
public void GetDefault_PassInteger_Return0()
{
    var result = DefaultCreator.GetDefault(typeof(int));
 
    Assert.That(result, Is.EqualTo(0));
}

And write the simplest solution that makes it pass:

public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type == typeof(int))
        {
            return 0;
        }
 
        return null;
    }
}

So far so good but we’re not done yet – after writing a few more tests for double, float and long refactoring brought this solution:

public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type.IsPrimitive)
        {
            return 0;
        }
 
        return null;
    }
}

Test #4 – Structs

Still with me... good – what about a complex value type :

[Test]
public void GetDefault_PassStruct_ReturnEmptyStruct()
{
    var result = DefaultCreator.GetDefault(typeof(MyStruct));
 
    Assert.That(result, Is.TypeOf<MyStruct>());
}

Now that we have a failing test – we can add functionality to fix it:

public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
 
        return null;
    }
}

Run all of the tests and that’s it – we have a class that mimics default(T) at run-time one step at a time.

The end

Of course I could have created this class without unit tests but I wanted to show a simple (but not too simple) example that shows how to use unit tests as a design tool.

 

Happy coding…

References
Published at DZone with permission of Dror Helper, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Sirikant Noori replied on Fri, 2012/03/30 - 1:20pm

Although TDD is not that simple the example shown here is a very good demonstation of how helpful can be. TDD is a very disciplined practice that requires excellent knowledge of unit testing and the domain of the system under development. In any case congratulations for the case described here :-)

Java Exam

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.