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.
You must be logged in to post a comment.