dynamic C# in unit tests

I’ve been writing some unit tests lately that require quite a bit of casting. This gets tiring pretty fast so I went ahead and decided to give the dynamic keyword a try. I’ll show the before and after examples and let you decide.

Here is the non-dynamic version.

[Test]
public void InvokeWithAddPlusInvokeTest()
{
    string code = "f(1 + 2) + g()";
    var b1 = (BinaryExpression)this.pipeline.Compile(code);

    var f = (MethodInvokeExpression)b1.Left;
    var g = (MethodInvokeExpression)b1.Right;

    var b2 = (BinaryExpression)f.Parameters.Single();

    var one = (PrimitiveExpression)b2.Left;
    var two = (PrimitiveExpression)b2.Right;

    Assert.That(b1.Operator == BinaryOperator.Add);
    Assert.That(b2.Operator == BinaryOperator.Add);

    Assert.That(((ReferenceExpression)f.Target).Name == "f");
    Assert.That(((ReferenceExpression)g.Target).Name == "g");
    Assert.That(one.Value == "1");
    Assert.That(two.Value == "2");
}

In this test I am compiling an expression into an AST and digging around to verify that the correct nodes were created in the right places in the tree.

Here is the dynamic version.

[Test]
public void InvokeWithAddPlusInvokeTest()
{
    string code = "f(1 + 2) + g()";
    dynamic b1 = this.pipeline.Compile(code);
    dynamic b2 = Enumerable.Single(b1.Left.Parameters);

    Assert.That(b1.Operator == BinaryOperator.Add);
    Assert.That(b2.Operator == BinaryOperator.Add);

    Assert.That(b1.Left.Target.Name == "f");
    Assert.That(b1.Right.Target.Name == "g");
    Assert.That(b2.Left.Value == "1");
    Assert.That(b2.Right.Value == "2");
}

A lot shorter that’s for sure. The only downside is that if I change the nodes I will no longer get compile time warnings… but I will get unit test errors so this shouldn’t theoretically matter. I also no longer get intellisense so I either have to just know the structure of the objects or use the debugger to figure it out. Still the simplicity is looking good.

Drop a brain bomb

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s