Wednesday, May 5, 2010

You don’t understand everything until you understand Nothing

Here’s a piece of code that might or might not do what you expect. (It depends on what you expect it to do.)

Dim someAge = "999"
Dim parsedAge As Integer? = If(someAge = "999", Nothing, Integer.Parse(someAge)) 

Challenge

What will the parsedAge variable contain?

Answer

It will be a nullable integer with no value, right? Ehh, no wrong!

-So, what will it be?

Well, it will be a nullable integer – that’s the easy part – but it will have a value, zero (0)! Is this what you expected? It’s not what I expected when just gleening over the code. It’s not wrong or anything, it’s just that it’s not particularly intuitive.

It might be easier to see what happens here if we try to rewrite the same code in C#:

string someAge = “999”;
int? parsedAge = someAge == “999” ? null : int.Parse(someAge);

This will not even compile because the ternary operator must evaluate to a type and the compiler can’t figure out which type you want since an int value and null can never be of the same type.

So, why does it compile in VB? Well, because…

… Nothing is not the same as null…

- Huh? Nothing in VB is the same as null in C# right?

- Ehh, wrong!

Nothing is much more like the “default” keyword in C#. Nothing can be assigned to value type variables which will contain the default value of that type:

So let’s write C# code that is in fact equivalent to the VB code:

string someAge = “999”;
int? parsedAge = someAge == “999” ? default(int) : int.Parse(someAge);

Now, ofcourse “default(int)” will always return “0” so we could just as well write this:

int? parsedAge = someAge == “999” ? 0 : int.Parse(someAge);

Now it might be a bit more clear what happens; the ternary operator will always return an integer, either zero or the parsed string value, it will never return null and it will never return a nullable integer.

Now this is probably what threw me off to begin with: the result of the ternary operator is assigned nullable integer, leading us to believe that the result of the operator is a nullable integer when it infact never is. An int will be implicitly converted to a nullable int so the compiler will not complain here even though we technically have a type mismatch.

Thursday, February 25, 2010

Return from sequence in FakeItEasy

I added a nifty little feature in FakeItEasy today, not 100% sure about the naming though so if you have any ideas pleas tell me. The idea is that when you configure a call you can specify several values and each time a call is made to the configured member (property or method) the next value from the collection will be returned. Here’s what it looks like in action:

public interface ICurrentTimeProvider
{
    DateTime CurrentTime { get; }
}
 
[Test]
public void Example()
{
    var timeProvider = A.Fake<ICurrentTimeProvider>();
 
    A.CallTo(() => timeProvider.CurrentTime).ReturnsNextFromSequence(
        DateTime.Parse("2000-01-01 01:00"),
        DateTime.Parse("2000-01-01 01:01"),
        DateTime.Parse("2000-01-01 01:02"));
 
    Console.WriteLine(timeProvider.CurrentTime); // Writes 2000-01-01 01:00
    Console.WriteLine(timeProvider.CurrentTime); // Writes 2000-01-01 01:01
    Console.WriteLine(timeProvider.CurrentTime); // Writes 2000-01-01 01:02
}

Wednesday, January 6, 2010

Not implemented? Implemented.

I use the System.NotImplementedException a lot, whenever I create a new method I have it throwing this until I have let tests drive actual functionality of the method. There is a slight danger in this though (although better than the alternative) in that I might forget to implement a function and this exception creeps into production.

The other day I modified the snippet I use so that it outputs pre processor directives, so that the compiler will refuse to compile the code if I forget to implement such a method.

#if DEBUG
            throw new NotImplementedException();
#else
#error "Must be implemented to compile in configurations where the DEBUG constant is not defined."
#endif

Sunday, December 27, 2009

Argument validation in FakeItEasy

I created two more screencasts on FakeItEasy, these two are on the subject on argument validation, I’ve increased the font size and put some compressor on the audio to improve the quality a bit.

 

Saturday, December 26, 2009

The basics of FakeItEasy

I thought I’d take a stab at screencasts so here’s my first attempt, it’s a quick overview of the FakeItEasy framework:

(I would highly recommend that you watch it in HD-quality, otherwise the text will not be readable.)

Saturday, December 19, 2009

Configuring any call to an object

I’ve just updated the way to configure any call to faked objects in FakeItEasy, the syntax is new and also you can now configure return values.

Let’s say you have an interface providing localized text resources like this:

public interface ILocalizedResources
{
    string SomeText { get; }
    string SomeOtherText { get; }
}

When you fake this interface any of the properties would return null when not configured but you might have several tests that are dependant on that the values are non null strings but still you don’t want to have to configure each individual property in the set up of you fixture. Now you can do exactly that:

var resources = A.Fake<ILocalizedResources>();
Any.CallTo(resources).WithReturnType<string>().Returns("");

Of course you can still configure any call to do anything you want just as before, for example:

var resources = A.Fake<ILocalizedResources>();
Any.CallTo(resources).Throws(new Exception());

 

Technorati-taggar: ,,,,,,

Thursday, December 10, 2009

T4

No, not that crappy movie but Text Template Transformation Toolkit.

I’ve played around with T4 every now and then over the last year but I’ve struggled to find any really good source for learning more. I guess the man who stands out from the crowd is Oleg Sych who has blogged about it en masse.

I’m watching a new screen cast by him on Channel 9 right now and it’s really good so please check it out.