Integration Testing In Memory Compiled Code with Roslyn

Georg Dangl by Georg Dangl in DotNet Friday, April 07, 2017

Friday, April 07, 2017

Integration Testing In Memory Compiled Code with Roslyn
Posted in DotNet

Have you ever written code to generate code? Probably.

Have you ever written proper integration tests for that? Probably not.

There is now a follow up article that uses the latest .Net project format in Visual Studio 2017. This post is still displaying the now deprecated project.json configuration

Everyone's done it - write code that writes code. Be it for converting from an esoteric Domain Specific Language, generating from a set of known data or for any other reason. It happens a lot, it's useful a lot, but it's not tested a lot. Testing such code has always been inconvenient, did involve a lot of disk IO and quite often relied on scripts and manual work. Luckily, with dotnets Roslyn compiler, there are NuGet packages for code analysis and compilation available that make all of this so easy!

The complete sample repository is available at GitHub. Here are the interesting parts:

It starts with the CodeGenerator  which does what it's name implies - it creates code. In this case, it's a simple class that has one method: AddIntegers().

This project.json is a regular, xUnit enabled, configuration file. There is a reference to the Microsoft.CodeAnalysis.CSharp package. That one will bring the Roslyn API to your project.

The actual integration test class is quite big, so let's break it down into it's functional units: 

  • GenerateCode() does just that - it gets the string representation of the sourcecode
  • CreateCompilation() takes the sourcecode, adds assembly references and turns it into a CSharpCompilation object
  • CompileAndLoadAssembly() now invokes the Roslyn API to compile onto a MemoryStream, then loads it and makes the content available
  • Finally, CallCalculatorMethod() uses reflection on the newly generated assembly and invokes the AddIntegers() method

This is a really interesting approach on tackling code generation. While I got the initial bits to set this up from Tugberk Ugurlus blog, I've had a project of my own where I did some heavy code generation (for correcting Xml documents) where I needed that. There's also code that works both in .Net Core and the full .Net framework.

Happy compiling!


Share this post


comments powered by Disqus

About me

Hi, my name's George! I love coding and blogging about it. I focus on all things around .Net, Web Development and DevOps.

DanglIT

Need a partner for DevOps, Web Services or Software Development?

Contact me at [email protected], +49 (173) 56 45 689 or visit my professional page!

Dangl.Blog();
// Just 💗 Coding

Social Links