Friday, July 31, 2009

Event raising syntax

Syntax for event raising is kind of awkward across the line, and for good reason, there simply is no really good way of doing it since an event always has to be positioned to the of an event attachment or detachment (+= or –=).

Just from the top of my head I think the way it’s done (or rather one of the ways you can do it) in Rhino Mocks is something like this:

var foo = MockRepository.GenerateMock<IFoo>();
foo.Raise(x => x.SomethingHappened += null, foo, EventArgs.Empty);

I think (I have not implemented this yet so I’m not sure it works) that I just came up with a rather different and maybe simpler way of doing it for Legend.Fakes. If it’s simpler or not I’ll leave up to you, but there’s a definite benefit in that it’s type safe on the event argument:

var foo = A.Fake<IFoo>();

// with sender explicitly:
foo.SomethingHappened += Raise.With(foo, EventArgs.Empty).Now;

// with the fake object as sender:
foo.SomethingHappened += Raise.With(EventArgs.Empty).Now;

Legend.Fakes configuration fluent interface

As I mentioned in my earlier post one of the things I want to avoid in my mock-/stub-/fake-framework is extension methods that clutter intellisense, this means that you have to get a configuration object to be able to start configuring your fake, don’t be afraid though, it’s really easy and there are two ways to do it. The first is to call the static method “Fake.Configure(object fakedObject)” with the fake object you want to configure, but you can also import the namespace “Legend.Fakes.ExtensionSyntax” and now you can call the “Configure” extension method directly on your faked object. If you do the latter you will have ONE extension method cluttering intellisense, but I can live with just one. Once you have the configuration object you have a fluent interface API.

IPerson person = A.Fake<IPerson>();

// Static method...
Fake.Configure(person);

// Once Legend.Fakes.ExtensionSyntax is imported you can use...
person.Configure();

 

When you have created a fake, the interface of the fake is a lot more discoverable since intellisense shows you what interface it provides: nonCluttered

The fluent interface is context aware so subsequent calls will only have certain options available depending on the call before. For example you can only specify a return value if the call you’re configuring is not a void call:

functionCall

A void call would look like this:

voidCall

Here’s some example configuration code:

var file = A.Fake<IFile>();

file.Configure()
    .CallsTo(x => x.Delete())
    .Throws(new NotSupportedException("You're not allowed to delete a file."))
    .Once();

file.Configure()
    .CallsTo(x => x.GetFileSizeInBytes()).Returns(400);

file.Name = "c:\filename.txt";

Wednesday, July 29, 2009

Introducing Legend.Fakes

OK, you’ll think I’ve lost it – or maybe you never thought I had it – but I’m creating my own mocking framework.

Why? Well, first of all because I wanted a framework that is more semantically correct and easier to understand so instead of distinguishing between mocks and stubs it just produces “fakes”, if a fake is a mock or a stub depends on the use of it. I also wanted a simpler and cleaner syntax for configuration, I’m really not a fan of the many extension methods cluttering Intellisense in your tests when using Rhino Mocks (although I really love Rhino Mocks).

clutternedIntellisense

I also thought it would be a really nice learning experience. Finally there are a few features I think will be cool that I will include that no other framework has (to my knowledge, though I’m only really familiar with Rhino).

But the main feature is and should be ease of use, so, to create a fake object (whether it’s a mock or a stub) you’d write this:

IFoo foo = A.Fake<IFoo>();

I’ll write more about other features, my learning experience while implementing this and post code soon.

Sunday, July 5, 2009

Round and round (my head spins)

A year or so ago I ran into a piece of code that made me a little dizzy and nauseous. I've created a piece of code similar to the code in question but the original code was in VB so I can't truly reproduce it but this will have to suffice. Can you figure out what the code does (line 7 in particular)?

public class Foo
{
    private string scoreLabelText;

    public Foo(decimal score)
    {
        score = (Convert.ToInt32((score * 10) / 5) * 5) / 10m;
        this.scoreLabelText = score.ToString();
    }
}

I figured it did pretty much nothing and thought that it had gotten in there by mistake or because some code had changed around it and that it had been significant in the past but wasn’t any more. Normally I would just have deleted it but I was lucky in that I could run a svn-blame and see who wrote it. So I called him and said something like “you’re never gonna be able to talk your way out of this one!”. The thing was, he could, since the code actually does something, it’s just that it’s totally non obvious. What it does is that it rounds the value to the nearest multiple of 0.5. For example…

  • 14.234 = 14
  • 14.44 = 14.5
  • 93.1 = 93
  • 93.71 = 93.5

What brought me to writing this blog post was that a guy new to the project ran into this same piece of code this Friday and had the same initial reaction as I did, he wanted to delete the line. That the "algorithm” is actually buggy is beside the point, the point is that code should always express it’s intent. The following would be a lot easier to understand:

public class Foo
{
    private string scoreLabelText;

    public Foo(decimal score)
    {
        var roundedScore = RoundToNearestHalfOrIntegerValue(score);
        this.scoreLabelText = roundedScore.ToString();
    }

    private static decimal RoundToNearestHalfOrIntegerValue(decimal value)
    {
        return (Convert.ToInt32((value * 10) / 5) * 5) / 10m;
    }
}

So just by moving the hard to decipher line into a method of its own we’ve made it a lot easier to understand and it’s also a lot less likely to be changed by someone who doesn't understand what the code should do.

As I said earlier there’s also a bug in the code. The bug is that it will round half way values down sometimes, for example 1.25 will be rounded to 1 instead of 1.5. I consider this a bug in this case since it’s not what’s intended even though it’s not necessarily an invalid way of doing rounding (it’s almost bankers rounding). A more to the point algorithm solves this problem and actually is a little more readable to. Note that this is not the only algorithm I could’ve chosen for this task, it’s just that it’s the one that I think is the most readable in the specific context.

public class Foo
{
    private string scoreLabelText;

    public Foo(decimal score)
    {
        var roundedScore = RoundToNearestHalfOrIntegerValue(score);
        this.scoreLabelText = roundedScore.ToString();
    }

    private static decimal RoundToNearestHalfOrIntegerValue(decimal value)
    {
        return Math.Round(value * 2m) / 2m;
    }
}