« Persistent Hash Codes | Main | Always wrap GZipStream with BufferedStream »

01 May 2012

Run MbUnit v2 tests under .NET 4

We still use MbUnit v2 for some of our assemblies, primarily because the items mentioned in the migration guide still haven't been implemented in MbUnit v3, and we haven't taken the time to port the tests to NUnit.

I wanted to compile our code for .NET 4 and still run all the existing tests against it.

The test runner (MbUnit.Cons.exe) is a .NET 1.1 app, so by default it will fail to load a .NET 4 test assembly. You can use the <supportedRuntime> configuration element to force the program to run under .NET 4, but it still fails to load the test assembly.

The message printed at the console isn't helpful, but if you debug the test runner, the following exception occurs:

NotSupportedException: This method implicitly uses CAS
policy, which has been obsoleted by the .NET Framework.
In order to enable CAS policy for compatibility reasons,
please use the NetFx40_LegacySecurityPolicy configuration
switch.
Please see http://go.microsoft.com/fwlink/?LinkID=155570
for more information.

This occurs because MbUnit uses the obsolete Assembly.Load(string, Evidence) method. To fix this, add the NetFx40_LegacySecurityPolicy configuration element, as instructed by the exception message.

Ultimately, your MbUnit.Cons.exe.config file should look as follows:

<?xml version="1.0" encoding="utf-8" ?>
<configuration> 
  <runtime>
    <!-- Don't kill application on first uncaught exception. -->
    <legacyUnhandledExceptionPolicy enabled="1" />

    <!-- Use legacy CAS policy so MbUnit's assembly loading succeeds. -->
    <NetFx40_LegacySecurityPolicy enabled="true"/>
  </runtime>

  <!-- Force use of .NET 4. -->
  <startup>
    <supportedRuntime version="v4.0" />
  </startup> 
</configuration>

With this new configuration, MbUnit can successfully run under .NET 4 and load .NET 4 assemblies. However, it still runs as a 32-bit process, so "Any CPU" test assemblies will get loaded as 32-bit. To make it run as 64-bit, you can use the CorFlags utility. As per the StackOverflow wiki, an "Any CPU" application should be a PE32 executable with the 32BIT flag cleared.

To change MbUnit to an "Any CPU" executable (so it runs as 64-bit on an x64 system), run:

CorFlags /UpgradeCLRHeader /32BIT- MbUnit.Cons.exe

Posted by Bradley Grainger at May 01, 2012 07:30 AM