Major Hack: Repository Tests With NHibernate And SQLite on a CI Server

I recently setup my first continuous integration build server using JetBrains’ TeamCity product, and it couldn’t have been much simpler.  However I kept running into an issue with my test projects whenever I was using NHibernate or SQLite (very useful or regression tests against an in-memory database).

The Problem

Everything would run correctly locally using MSTest, but when TeamCity ran the tests I would get the following error:

Unable to load type 'NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle' during configuration of proxy factory
class.
Possible causes are:
- The NHibernate.Bytecode provider assembly was not deployed.
- The typeName used to initialize the 'proxyfactory.factory_class'
property of the session-factory section is not well formed.

Solution:
Confirm that your deployment folder contains one of the following
assemblies:

Of course I’ve seen this error before and I double checked that I had a reference to the NHibernate bytecode provider and that my NHibernate.config file was configured correctly.  I thought maybe this was a x86 vs x64 issue, but that also did not seem to be the case.

Eventually running MSTest locally through the command line reproduced the error, and after I searched around for a while I found that NHibernate.ByteCode.Castle.dll was not be deployed into the specific TestProject\bin\Release\ folder (and neither was SQLite).

I made sure my test project had a reference to both DLLs, that is was set to copy local, and still they were not copied to my “deployment” directory.

The Reason

From what I could gather, msbuild was being ‘smart’ and optimizing my build such that the bytecode and SQLite DLLs were not being included since they were never directly referenced in code.  This is because they are referenced only in the NHibernate.config file.

The Solution (aka Major Hack)

In order to get the proper DLLs included in the build I had to reference them somewhere in code, so I made a totally unreachable class that should never be instantiated, as follows:

/// <summary>
/// NOTE: This is a hack to make sure that the castle 
/// and SQLLite assemblies are copied into the Test deployemnt directory
/// This class never gets called.
/// </summary>
public class ContinuousIntegrationDeploymentHack
{
    public ContinuousIntegrationDeploymentHack()
    {
        new NHibernate.ByteCode.Castle.ProxyFactoryFactory();
        new System.Data.SQLite.SQLiteException();
 
        throw new Exception("This class should never be called or instantiated");
    }
}

Adding this class anywhere into my test project does the trick – the castle bytecode and SQLite DLLs are now copied into the deployment directory and all tests run correctly.

The Future

I am sure the proper way to solve this was to use MSBuild or NAnt and copy the files correctly, but I am currently using the easy TeamCity sln2008 runner and thus there are no custom tasks that I can run.

9 Comments

  • csproj files are msbuild files. Write your custom task and put it in one of your project files.

  • Hi Scott!

    Thanks! This was very helpful!

    One little change to the hack, to avoid the creation of new instances, I've just added a private variable named "requiredButNeverUsed":

    private NHibernate.ByteCode.Castle.ProxyFactoryFactory requiredButNeverUsed;

    This will not create a new instance, and msbuild will copy the required file anyways =)

    Thanks!

  • Hey there! Do you know if they make any plugins to assist with Search Engine Optimization? I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very good gains. If you know of any please share. Kudos!

  • Hmm it appears like your blog ate my first comment (it was super long) so I guess I'll just sum it up what I had written and say, I'm thoroughly enjoying your blog. I as well am an aspiring blog blogger but I'm still new to the whole thing. Do you have any points for novice blog writers? I'd definitely appreciate it.

  • Peculiar article, just what I was looking for.

  • continuously i used to read smaller articles which
    also clear their motive, and that is also happening
    with this post which I am reading now.

  • Check out my web page for lots more details. On the contrary,
    payday services distance themself money from either
    in a significant of checks and also cash or correct extract
    it anywhere from your salary site.

  • It asks you to simple an application form online and basically soon as in which is approve your become eligible to
    amount is copied within 24 moments. But you must
    be very careful with this.

  • This website is extremely good. How did you make it !

Comments have been disabled for this content.