I'm working on building a Dynamic context driver for LINQPad for IBM Db2 databases. I've been test driving the majority of the code, and I think I'm about done getting all the information I need about the database that I need. (I might need more later, but for now it seems sufficient). I downloaded the git repository for the PostgreSQL context driver and see (somewhat) how it is built. There are not enough tests for my liking to feel confident that I am building the assembly. But then I got to thinking if I was to start building this dynamic assembly I have no clue how to test drive this. I wanted to start off simple like this:
[TestFixture]
public class Db2DynamicAssemblyBuilderTests
{
[Test]
public void DynamicClassHasMatchingNameAsTable()
{
List<Models.Db2TableInformation> tableInformation = new List<Models.Db2TableInformation>();
tableInformation.Add(new Models.Db2TableInformation()
{
Schema = "Schema",
TableName = "TableName"
});
AssemblyName assemblyToBuild = new AssemblyName(@"c:\temp\someassembly.dll");//somehow build this with a dynamic name???? i'll figure this out
string nameSpace = "LINQPad.User";
string typeName = "TypeDataContext";
var target = new Db2DynamicAssemblyBuilder(assemblyToBuild, nameSpace, typeName);
target.Build(tableInformation);
//??? Load assembly?
//Get Class LINQPad.User.Schema.TableName (or maybe just LINQPad.User.TableName...not sure yet)
}
}
so is this the right approach? Is this how I would do it?
To generalize your question, you're asking how best to unit-test an assembly that gets built dynamically. The difficulty is that the assembly in question doesn't exist until you've run code to generate it, so you can't reference the assembly and statically bind to it.
I can think of two workarounds. Either have two separate projects - one that generates the assemblies that get build dynamically, and another project that reference and tests those assemblies.
The other workaround is to load the assembly and types dynamically with Assembly.LoadFile and then GetType (...) on the assembly. Then you can instantiate it with Activator.CreateInstance and then cast the object to dynamic to access its properties and methods.