Apr 27 2010

Using Moq Dynamically

Category: MVCMatt @ 14:45

The TestControllerBuilder in MVCContrib’s TestHelper library has a hard dependency on Rhino Mocks.  I’m not a big fan of Rhino Mocks, I prefer to use Moq, and while it’s not a big deal to reference two separate mocking libraries, I’d rather just have one mocking library in my project.  I’m working on a patch to address this open workitem in MVCContrib.  I don’t want to create a hard reference to Moq, so that means I have to access Moq, and all it’s generic types and methods, using reflection.  This post presents my Moq proxy class, based on a similar idea from StructureMap’s auto-mocking container.

The TestControllerBuilder in MVCContrib.TestHelper is a handy class for attaching mocks to an MVC Controller class to facilitate testing.  Unfortunately, it uses Rhino Mocks, which means you must include Rhino Mocks in your projects in order to leverage it.  My test projects already reference Moq (my preferred testing framework), and I don’t like the idea of carrying around two libraries that provide the same capabilities.  I’m not the only one, as there has been an open work item to address this issue for quite some time now. One of the nice things about Open-Source Software is that instead of wasting energy complaining about something, I can try to fix it. 

I have three main goals for the fix.  First, it should not be a breaking change.  Existing consumers of the API should be unaffected.  Second, it should not create a hard reference between MVCContrib and Moq.  MVCContrib is already using Rhino Mocks for its own testing, and I’m trying to remove the need for referencing two mocking frameworks in my own projects, so it would be a bit ironic if I required MVCContrib to pick up a dependency on Moq.  Finally, I want it to be very simple to swap out the mocking library; in fact, I’d like it to automatically use whichever library is available.  I’d even like it to be pluggable so that a different mocking library could be plugged in if desired.

I’m not 100% tied to this approach yet (I’m still thinking of this more as a spike for now), but I’m using the strategy pattern to decouple TestControllerBuilder from the mocking library.  There are other places in MVCContrib’s TestHelper library that are doing mocking, so I will probably change my approach, but this worked well as a proof-of-concept.  TestControllerBuilder now accepts an IControllerBuilderStrategy that handles the actual mocking and any other library-specific setup.  The interface is quite simple:

public interface IControllerBuilderStrategy 
{
    void Setup(TestControllerBuilder testControllerBuilder);
}

By default, TestControllerBuilder uses the RhinoMocksControllerBuilder (this satisfies my first goal: existing consumers of the API will get the exact same behavior as before).  Because MVCContrib.TestHelper has a direct dependency on Rhino Mocks, RhinoMocksControllerBuilder is a straight-forward refactoring of TestControllerBuilder’s mock-dependent logic into a new class:

public class RhinoMocksControllerBuilder : IControllerBuilderStrategy 
{
    protected MockRepository _mocks = new MockRepository();

    public void Setup(TestControllerBuilder testControllerBuilder)
    {
        var httpContext = _mocks.DynamicMock<HttpContextBase>();

        var request = _mocks.DynamicMock<HttpRequestBase>();
        var response = _mocks.DynamicMock<HttpResponseBase>();
        var server = _mocks.DynamicMock<HttpServerUtilityBase>();
        var cache = HttpRuntime.Cache;

        SetupResult.For(httpContext.Request).Return(request);
        SetupResult.For(httpContext.Response).Return(response);
        SetupResult.For(httpContext.Session).Return(testControllerBuilder.Session);
        SetupResult.For(httpContext.Server).Return(server);
        SetupResult.For(httpContext.Cache).Return(cache);

        SetupResult.For(request.QueryString).Return(testControllerBuilder.QueryString);
        SetupResult.For(request.Form).Return(testControllerBuilder.Form);
        SetupResult.For(request.AcceptTypes).Do((Func<string[]>)(() => testControllerBuilder.AcceptTypes));
        SetupResult.For(request.Files).Return((HttpFileCollectionBase)testControllerBuilder.Files);

        Func<NameValueCollection> paramsFunc = () => new NameValueCollection { testControllerBuilder.QueryString, testControllerBuilder.Form };
        SetupResult.For(request.Params).Do(paramsFunc);

        SetupResult.For(request.AppRelativeCurrentExecutionFilePath).Do(
            (Func<string>)(() => testControllerBuilder.AppRelativeCurrentExecutionFilePath));
        SetupResult.For(request.ApplicationPath).Do((Func<string>)(() => testControllerBuilder.ApplicationPath));
        SetupResult.For(request.PathInfo).Do((Func<string>)(() => testControllerBuilder.PathInfo));
        SetupResult.For(request.RawUrl).Do((Func<string>)(() => testControllerBuilder.RawUrl));
        SetupResult.For(response.Status).PropertyBehavior();
        SetupResult.For(httpContext.User).PropertyBehavior();

        _mocks.Replay(httpContext);
        _mocks.Replay(request);
        _mocks.Replay(response);

        testControllerBuilder.HttpContext = httpContext;
    }
}

Things get a little trickier for the Moq version.  Since TestHelper can’t reference Moq directly, it can’t use the API directly.  I decided to use the proxy pattern after reviewing how StructureMap’s AutoMocking Container handles a similar situation.  The builder itself is still very straight forward.  Though the proxy’s methods don’t map one-to-one to the underlying Moq API, they are pretty close:

public class MoqControllerBuilder : IControllerBuilderStrategy
{
    private static Exception _loadException;
    private static MoqProxy _proxy;

    static MoqControllerBuilder()
    {
        try
        {
            _proxy = new MoqProxy();
        }
        catch (Exception ex)
        {
            _loadException = ex;
        }
        
    }

    public void Setup(TestControllerBuilder testControllerBuilder)
    {
        if (_proxy == null)
        {
            throw new InvalidOperationException("Cannot use MoqControllerBuilder because an error occured while loading Moq.",
                                                _loadException);
        }

        var httpContext = _proxy.DynamicMock<HttpContextBase>();

        var request = _proxy.DynamicMock<HttpRequestBase>();
        var response = _proxy.DynamicMock<HttpResponseBase>();
        var server = _proxy.DynamicMock<HttpServerUtilityBase>();
        var cache = HttpRuntime.Cache;

        httpContext.ReturnFor(c => c.Request, request.Object);
        httpContext.ReturnFor(c => c.Response, response.Object);
        httpContext.ReturnFor(c => c.Session, testControllerBuilder.Session);
        httpContext.ReturnFor(c => c.Server, server.Object);
        httpContext.ReturnFor(c => c.Cache, cache);
        httpContext.SetupProperty(c => c.User);

        request.ReturnFor(r => r.QueryString, testControllerBuilder.QueryString);
        request.ReturnFor(r => r.Form, testControllerBuilder.Form);
        request.ReturnFor(r => r.Files, (HttpFileCollectionBase)testControllerBuilder.Files);
        request.CallbackFor(r => r.AcceptTypes, () => testControllerBuilder.AcceptTypes);
        request.CallbackFor(r => r.Params, () => new NameValueCollection { testControllerBuilder.QueryString, testControllerBuilder.Form });
        request.CallbackFor(r => r.AppRelativeCurrentExecutionFilePath, () => testControllerBuilder.AppRelativeCurrentExecutionFilePath);
        request.CallbackFor(r => r.ApplicationPath, () => testControllerBuilder.ApplicationPath);
        request.CallbackFor(r => r.PathInfo, () => testControllerBuilder.PathInfo);
        request.CallbackFor(r => r.RawUrl, () => testControllerBuilder.RawUrl);
        response.SetupProperty(r => r.Status);

        testControllerBuilder.HttpContext = httpContext.Object;
    }
}

The *real* fun happens in the proxy class. First is the MoqProxy class, which handles dynamically loading the Moq API and, using reflection, creating mock objects:

public class MoqProxy
{
    private Type _mockOpenType;

    public MoqProxy()
    {
        Assembly Moq = Assembly.Load("Moq");
        _mockOpenType = Moq.GetType("Moq.Mock`1");

        if (_mockOpenType == null)
        {
            throw new InvalidOperationException("Unable to find Type Moq.Mock<T> in assembly " + Moq.Location);
        }
    }


    public MockProxy<T> DynamicMock<T>()
    {
        return new MockProxy<T>(_mockOpenType.MakeGenericType(typeof(T)));
    }
}

The MockProxy<T> class is the proxy for the underlying Mock<T> type, which is the class used for setting up expectations.  This was a tricky class to implement due to the heavy use of generic parameters, but in the end, I managed to get it working:

public class MockProxy<T>
{
    private readonly Type _mockType;
    private PropertyInfo _objectProperty;
    private object _instance;

    public T Object 
    { 
        get
        {
            return (T)_objectProperty.GetValue(_instance, null);
        }
    }

    public MockProxy(Type mockType)
    {
        _mockType = mockType;
        _instance = Activator.CreateInstance(_mockType);
        _objectProperty = mockType.GetProperty("Object", _mockType);
    }

    private MethodInfo GetSetupMethod<TResult>() {
        var openSetupMethod = _mockType.GetMethods().First(m => m.IsGenericMethod && m.Name == "Setup");
        return openSetupMethod.MakeGenericMethod(typeof(TResult));
    }

    public void ReturnFor<TResult>(Expression<Func<T, TResult>> expression, TResult result)
    {
        var setupMethod = GetSetupMethod<TResult>();
        var setup = setupMethod.Invoke(_instance, new object[] { expression });
        var returnsMethod = setup.GetType().GetMethod("Returns", new [] {typeof(TResult)});
        returnsMethod.Invoke(setup, new object[] { result});
    }

    public void CallbackFor<TResult>(Expression<Func<T, TResult>> expression, Func<TResult> callback)
    {
        var setupMethod = GetSetupMethod<TResult>();
        var setup = setupMethod.Invoke(_instance, new object[] { expression });
        var returnsMethod = setup.GetType().GetMethod("Returns", new[] { typeof(Func<TResult>) });
        returnsMethod.Invoke(setup, new object[] {callback});
    }

    public void SetupProperty<TProperty>(Expression<Func<T, TProperty>> expression)
    {
        var openSetupMethod = _mockType.GetMethods().First(m => m.Name == "SetupProperty" && m.GetParameters().Length == 1);
        var setupMethod = openSetupMethod.MakeGenericMethod(typeof(TProperty));
        setupMethod.Invoke(_instance, new object[] {expression});
    }
}

Reflection is somewhat limited when it comes to working with overloaded generic methods.  I ended up using this approach for finding the desired overload via LINQ. 

With all the pieces in place, the TestControllerBuilder unit tests now pass when using either Rhino Mocks or Moq.  Again, this isn’t my final solution, I’m still waiting on feedback on a few possible approaches to decide what’s going to actually be implemented, but the MoqProxy is probably going to be a key piece of whatever solution I move forward with.

Tags:

Apr 15 2010

Towards a better Windows Communication Foundation

Category: WCFMatt @ 12:48

Windows Communication Foundation (WCF) is The One Way to implement inter-process communication on the .NET platform.  Well, it’s not really the only way, but it’s certainly the most common way.  It’s a bit misused.  Unfortunately, WCF suffers from numerous problems.  It is extremely configuration heavy, it has known design issues, and it has a learning curve that nearly rivals Lisp.  We need a better way to handle inter-process communication in the .NET world.  I’m not proposing a solution in this post, merely throwing out some ideas.  Feedback is welcome in the comments!

What is Windows Communication Foundation?

From MSDN:

Windows Communication Foundation (WCF) is Microsoft’s unified programming model for building service-oriented applications. It enables developers to build secure, reliable, transacted solutions that integrate across platforms and interoperate with existing investments.

Basically, WCF is a highly-configurable API for communication to/from services.  It’s the successor to both ASMX Web Services and .NET Remoting.  It has several advantages over both technologies, not the least of which is the separation of the “contract” from the implementation.  It’s quite useful for building loosely-coupled, standards-compliant end points. 

What’s wrong with it?

Configurability adds complexity, and WCF is very configurable, making it very complex.  There are tools written around managing the app.config entries that it requires.  You can choose to configure WCF via code, but this is not the recommend approach, and it’s still more complicated than it should be.

WCF also suffers from some pretty serious design issues.  For whatever reason, even as we have reached the second major .NET revision since WCF was introduced, the WCF “dispose” semantics remain broken.

The “proxies” themselves are another problem with WCF.  They look exactly like a normal class.  If you hide them behind an interface reference, the fact that you are dealing with a proxy object can be totally obscured, leading to poor implementation choices downstream.  While this is certainly convenient in terms of cranking out code, the drawbacks can be severe.  Imagine how the following will perform if the IDataSource instance is actually a proxy for a remote object instead of a local object. 

public void ListResults(IDataSource source, int count)
{
    for (int i=0; i < count; i++)
    {
        //This is what we'd call a 'chatty' interface...
        Console.WriteLine(source.GetItem(i));
    }
}

In a nutshell, I’d summarize WCF as a tool that tries to solve every problem but only manages to become too complicated to effectively solve much of anything.  It tries to make a complex problem (inter-process communication) simpler by masking it under layer upon layer of abstraction.  This is exactly the same approach that ASP.NET WebForms took.  Does it work some of the time?  Sure.  But most of the time it causes far more pain than it prevents.

What should be done differently?

I think attempting to create a single, unified API that can solve every problem via reconfiguration is a really bad idea.  With WCF we can configure every single aspect of the end point, the transport, the channel, etc.  There are defaults for many things, but even using the defaults where possible won’t get your configuration much below 20 lines of app.config mess. 

Instead, I would like to see specialized APIs to tackle each type of problem.  (We’re already making a little progress on this front with things like NServiceBus, which provides an API that is tailored to the types of problems service buses are meant to solve.)  Instead of requiring extensive configuration, the APIs should adopt intelligent (but swappable) conventions, allowing users to get up and running with the API with near-zero configuration while still providing plenty of hooks for extensibility.  I think sacrificing some flexibility in order to avoid complexity is a good trade. 

Another problem: right now, I’d say that making synchronous calls is the path-of-least-resistance when using WCF.  Sure, WCF supports asynchronous calls, but I think most developers fall into the easy trap of making synchronous calls. I think the remote APIs should be asynchronous-by-default.  It should take (some) extra work to make synchronous inter-process calls, thereby redirecting developers towards a better design for their distributed systems.  Making synchronous web service calls is a good way to kill your system’s performance.

One common use case I keep bumping in to is making a Remote Procedure Call to a service on another physical machine.  Handling that with WCF requires extensive configuration on both ends.  I’m not sure exactly what I’d like to see on the server-side, but perhaps something like this (inspired by StructureMap):

public class MyServiceObjects : ServiceRegistry
{
    public MyServiceObjects()
    {
        //This would load default conventions for things like 
        //channel and endpoint settings, but it could be replaced
        //by your own conventions. 
        With.DefaultConventions();
        
        //By default, expose services over a TCP channel
        Expose<IDataSource>().Using<ConcreteDataSource>();
        
        //Changing to an alternate channel should still be trivial. 
        Expose<ICommandableThing>().OverHttps().Using<ConcreteCommandableThing>();
    }
}

Note that there are no app.config settings needed for this.  All the configuration data would come from the conventions (defined in code) or would be explicitly specified in the registry.  Are there downsides to this?  Sure: I can’t decide to change how my services are exposed without recompiling my application.  I don’t see that as being a big loss.

Client-side, I think it should be very clear when you are using a remote object.  The remote object should not pass for a local one (at least not without having to jump through a small hoop; after all, there are going to be times when treating it as a local object makes perfect sense).  The proxy should be asynchronous by default and support batching remote calls.  Here’s what my previous example might look like with such an API:

public void ListResults(string remoteSourceUrl, int count)
{
    var proxy = RemoteProxy.For<IDataSource>(remoteSourceUrl);

    using (proxy.BeginBatch())
    {
        for (int i=0; i < count; i++)
        {
            //The first lambda is the call on the data source.
            //The second lambda is the callback to run when the 
            //remote call completes. 
            proxy.Call(ds => ds.GetItem(i), item => Console.WriteLine(item));
        }
    }
}

So what do we do?

I’m not sure.  Microsoft has shown no real hint of backing off from WCF despite the overwhelming negative feelings that most of the .NET community has about it, but I don’t see a lot of effort by the community to develop alternatives aside from the various service buses.  Maybe I’m overlooking something (if so, let me know).  I’d love to work on something like this, but my workload is already overwhelming me.  If there’s an effort by someone out there to implement something along these lines though, I’d be game for helping out when/where I can.

Tags:

Mar 30 2010

Using Powershell to apply new C# field naming conventions

Category: PowerShellMatt @ 02:34

I recently found myself wanting to rename all the fields in several large projects to conform to a new naming scheme.  Sadly Resharper was not helpful here, so I turned to a combination of Regex and Powershell. 

Our team has recently revised our 7 year-old coding guidelines.  One of the guidelines that was changed concerned field naming.  Our previous guideline stated that fields should use an ‘m’ prefix with Pascal Casing, creating fields of the form “mFieldName”.  At the time the guidelines were written, .NET was still young, and the community hadn’t yet settled on a widely accepted standard.  Since then, most of the community seems to have gravitated towards using an underscore prefix for fields with camel casing, creating fields of the form “_fieldName”.  We finally decided to bite the bullet and switch our guideline to conform to the more generally accepted convention.  The problem is that we have a lot of code that uses the old style.  By “a lot”, I mean probably in the neighborhood of 100k lines of code across the various projects. 

One solution we discussed was to just leave existing fields alone, and only use the new convention when creating new code.  This would work, but since we use Resharper to enforce the naming conventions, it would create a lot of false warnings.  It also meant that we would be introducing some inconsistency into our code base, which we wanted to avoid.

One avenue that we explored was using Resharper to update all existing field names.  The Patterns functionality introduced in Resharper 5.0 might be able to accomplish this, but I was unable to figure out how. 

When that failed, James suggested that I try using Regex.  It took a bit of Powershell hacking, but I managed to come up with a script that worked.  I’ve applied it across thousands of classes, and it *appears* to rename things correctly.  Here’s the script:

   1: $regex = New-Object System.Text.RegularExpressions.Regex "(?:\W(?<name>m[A-Z][a-zA-Z0-9_]+))"
   2: Get-ChildItem * -Recurse -Include *.cs | ? {$_ -notmatch 'Resharper' } | ? {$_ -notmatch 'DecompilerCache' } | ForEach-Object { 
   3:     $text = [System.IO.File]::ReadAllText($_.FullName)
   4:     $matches = $regex.Matches($text)
   5:     $matches | ForEach-Object { 
   6:         $toReplace = $_.Groups["name"].Value 
   7:         $newValue = "_" + [System.Char]::ToLower($toReplace[1]) + $toReplace.Substring(2)
   8:         $text = [System.Text.RegularExpressions.Regex]::Replace($text, "(?:(?<prefix>\W)" + $toReplace + ")", "`${prefix}$newValue")
   9:     } 
  10:     [System.IO.File]::WriteAllText($_.FullName, $text)
  11: }

The first line creates a new Regex object that will match things of the form “mFieldName” that are prefixed by a non-word character.  Next, the script recursively iterates through C# files, ignoring the contents of the Resharper directory as well as the DecompiledSources directory.  For each matched file, the script grabs the full text from the file, finds the field names that need to be changed (if any), then uses a different regex to replace the field name in the text.  Note that simple string.Replace won’t work here since the replacement must account for the non-word character that prefixes the filed name, otherwise things such as “NumWhatever” will be transformed as well (as I found out with an earlier version of this script).  Finally, the modified text is written back to the file.

It’s not terribly pretty, and it certainly isn’t innovative, but it did save me quite a bit of time this morning. :)

Tags:

Mar 12 2010

Client-Side Validation with ASP.NET MVC 2.0 Futures

Category: ASP.NET | MVCMatt @ 16:26

Just a quick post to hopefully save others some time.  ASP.NET MVC 2.0 has built-in support for client-side validation, but it doesn’t work with the expression-based BeginForm HtmlHelper methods that are available in the ASP.NET MVC Futures assembly.  I also don’t like that I have to call a separate helper method to set my form up for validation.  To address these two limitations, I wrote my own extension method:

public static class ValidationHelper
{
    private const string LAST_FORM_ID_KEY = "_lastFormId";

    public static MvcForm BeginValidatedForm<TController>(this HtmlHelper helper, Expression<Action<TController>> action)
            where TController : Controller
    {
        helper.EnableClientValidation();

        var id = GetNextFormId(helper);

        TagBuilder builder = new TagBuilder("form");
        string str = helper.BuildUrlFromExpression(action);
        builder.MergeAttribute("action", str);
        builder.MergeAttribute("method", "POST");
        builder.GenerateId(id);
        helper.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag));

        var form = new MvcForm(helper.ViewContext);

        helper.ViewContext.FormContext.FormId = id;

        return form;
    }

    private static string GetNextFormId(HtmlHelper helper)
    {
        int count = (int) (helper.ViewContext.HttpContext.Items[LAST_FORM_ID_KEY] ?? 0);
        count++;

        helper.ViewContext.HttpContext.Items[LAST_FORM_ID_KEY] = count;

        return string.Format("form{0}", count);
    }
}

Now you can simply do like this:

<h1>Sign-up</h1>

<p>Signing up is easy <em>and</em> free!</p>

<% using (Html.BeginValidatedForm<SignupController>(c => c.Create(null)))
{ %>
    <fieldset>
        <div>
            <p>1) Choose a username:</p>
            <%=Html.EditorFor(m => m.Username) %><%=Html.ValidationMessageFor(c => c.Username) %>
        </div>
        <div>
            <p>2) What's your E-mail address? <span class="note">(<a href="#">Why do we need this?</a>)</span></p>
            <%=Html.EditorFor(m => m.Email)%><%=Html.ValidationMessageFor(c => c.Email) %>
        </div>
        <%=Html.SubmitButton("submit", "Start Raging Now!") %>
    </fieldset>
<%} %>

and get client-side validation (assuming you’ve set everything else up correctly).

Tags:

Mar 12 2010

Vote for me at CodeStock!

Category: MiscMatt @ 03:21

Voting is now open for CodeStock 2010 sessions!  I have three sessions submitted this year.  If you live in the Southeast, this conference is a real steal.  Early registration is just $55.  That’s $55 for a two-day conference, “buffet style” lunches, and a shirt.  Not bad!  If you register early, please consider voting for my sessions if they sound interesting to you:

Reducing Coupling through Inversion of Control, Dependency Injection, and Event Aggregation with StructureMap

Adding powerful search capabilities to your application with Lucene.NET and NHibernate Search

Improve your unit tests - a practical guide to Moq

Also be sure to check out James “poprhythm” Kolpack’s sessions as well:

Parallel Computing in .NET 4 with Visual Studio 2010

Windows PowerShell Introduction

Thanks, and I hope to see you at CodeStock!

Tags:

Mar 11 2010

Two things missing from C#

Category: .NETMatt @ 08:07

While building some ugly code to walk the Lucene.NET Query graph, I found myself needing two bits of functionality from C# that it sadly doesn’t provide.  There are arguments for and against each of these, but they certainly would have saved me some pain today.

Switching off of System.Type

The Lucene query graph is a nasty beast.  There’s an abstract base Query class, but no common way to iterate through the graph and extract criteria.  Instead, you have to process each concrete type separately.  An easy way to do this would be to use a switch statement off of the concrete query type and execute the corresponding logic to process the type.  Unfortunately, the C# switch statement only supports types that are convertible to Integer (and strings).  There are solutions, such as this, but why isn’t it built in to the framework?  Peter Hallam explains the reasons, but I don’t agree with most of his argument. Visual Basic’s equivalent of a switch statement allows for case statements to “overlap”, and it doesn’t seem to be causing catastrophic problems there.  I think it’s actually quite intuitive to expect that only the first matching case statement would be executed.  In any case, I’d love to see this added to C#.

Using ‘yield return’ to directly return an IEnumerable

The ‘yield return’ statement is incredibly useful, but I’ve found myself on multiple occasions using it to enumerate a hierarchical object graph.  In such situations, it’s quite annoying that I can’t just ‘yield return’ the entire child object IEnumerable list at once.  Instead, I have to manually iterate the child list and ‘yield return’ each result individually.  I see no reason (at all) why this extra step should be necessary.   Wes describes a possible way to implement this feature, and there’s a (closed as won’t fix) issue on Microsoft Connect with a slew of votes.

Tags:

Mar 9 2010

A troublesome brew: NHibernate + FluentNHibernate + SQLite on .NET 4.0

Category: TestingMatt @ 15:20

Mixing NHibernate, Fluent NHibernate, and SQLite on .NET 4.0 RC will lead to some major headaches.  There’s an easy fix, but it doesn’t work if you are using Resharper’s test runner.  If you’re using my personal favorite test runner, TestDriven.NET though, the fix is actually quite easy. 

We decided to use .NET 4.0 for the new super secret social networking site we’re working on, and since we’re starting out with a relational DB under the hood (that we fully plan to swap out for a NoSQL alternative later), we’re using NHibernate.  I hate NHibernate’s XML maps, so we’re also using FluentNHibernate.  When I’m using NHibernate, I like to use SQLite’s in-memory database for my unit tests, so now we’re looking at making three pieces of OSS play nice together on a not-quite-finished version of the .NET Framework.  Oh, and I’m also using Resharper 5.0 EAP.  :)

Getting things started is easy enough.  I grabbed the latest production release of NHibernate along with a compatible version of Fluent NHibernate.  I also grabbed the latest SQLite .NET assembly.  After adding references to the required bits, here’s my NHibernate bootstrapper:

public static class NHibernateBootstrapper
{
    private static Configuration _currentConfig;

    private static FluentConfiguration ConfigureMappings()
    {
        return Fluently.Configure()
            .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
            .ExposeConfiguration(c => _currentConfig = c);
    }

    public static ISessionFactory CreateSessionFactoryForTests()
    {
        return ConfigureMappings()
            .Database(SQLiteConfiguration.Standard.ShowSql().InMemory())
            .BuildSessionFactory();
    }

    public static ISessionFactory CreateSessionFactoryForProduction()
    {
        return ConfigureMappings()
            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("RageFeedData")))
            .BuildSessionFactory();
    }

    public static void CreateSchema(ISession session)
    {
        var exporter = new SchemaExport(_currentConfig);
        exporter.Execute(true, true, false, session.Connection, null);
    }

    public static void UpdateSchema()
    {
        var updater = new SchemaUpdate(_currentConfig);

        updater.Execute(true, true);
    }
}

And here’s my unit tests:

public abstract class InMemoryDatabaseFixture
{
    public ISession Session { get; private set; }

    [SetUp]
    public virtual void Prepare()
    {
        var factory = NHibernateBootstrapper.CreateSessionFactoryForTests();
        Session = factory.OpenSession();
        NHibernateBootstrapper.CreateSchema(Session);
    }

    [TearDown]
    public virtual void Cleanup()
    {
        Session.Dispose();
    }
}

[TestFixture]
public class RageletPersistanceTests : InMemoryDatabaseFixture
{
    [Test]
    public void CanCorrectlyPersistRagelet()
    {
        new PersistenceSpecification<Ragelet>(Session)
            .CheckProperty(r => r.Content, "Test content")
            .VerifyTheMappings();
    }
}

Simple enough, right? 

boom

Sadly, this fails gloriously when run with ReSharper’s test runner:

Mixed mode assembly is built against version 'v2.0.50727' of the runtime
and cannot be loaded in the 4.0 runtime without additional configuration information.

I found a solution, but it doesn’t work with Resharper 5.0 EAP.  I’m thinking that Resharper isn’t using the app.config file, but perhaps it’s something else.  Fortunately, running the tests with TestDriven.NET (my favorite test runner) worked perfectly.

Unfortunately, I wasted the better part of two weeks of “free time” trying to get things recompiled so that they would work without the app.config entry.  There are several breaking changes in .NET 4.0 apparently, and nothing that I tried worked.  Hopefully this isn’t a sign of pains to come. 

Tags:

Feb 23 2010

Easily override ToString using Moq

Category: MoqMatt @ 05:40

I recently discovered a rather annoying limitation in Moq: you cannot setup expectations on the ToString method.  For a good discussion of the issue, check out Sean’s post.  His solution was to add ToString explicitly to the interface you are mocking, but I don’t want to dirty up my interfaces unnecessarily.  Fortunately, Moq does allow you to create mocks that implement multiple interfaces, so you could move the ToString method to a dummy interface, and use Mock<T>.As to setup expectations on the dummy interface.  That’s the approach I took, but I wrapped it up in a nice extension method:

public static class MoqExtensions
{
    public static ISetup<IToStringable, string> SetupToString<TMock>(this Mock<TMock> mock) where TMock : class
    {
        return mock.As<IToStringable>().Setup(m => m.ToString());
    }
    
    //Our dummy nested interface.
    public interface IToStringable
    {
        /// <summary>
        /// ToString.
        /// </summary>
        /// <returns></returns>
        string ToString();
    }
}

Now I can setup expectations on ToString by simply using:

[Test]
public void ExpectationOnToStringIsMet()
{
    var widget = new Mock<IWidget>();
    widget.SetupToString().Returns("My value").Verifiable();

    Assert.That(widget.Object.ToString(), Is.EqualTo("My value"));

    widget.Verify();
}

Tags:

Feb 22 2010

Extending Moq: returning multiple results via lambdas

Category: MoqMatt @ 05:06

I have on several occasions wished that I could setup expectations in Moq for subsequent calls to a method.  For example, I might want Moq to return one value the first time a method is called, but a different value the second and third times.  Phil Haack has a nice way to achieve this, but his implementation only allows you to return a result.  What if you need something more advanced?  What if you want to return a value on the first call, throw an exception on the second, and return a value again on the third?  I ran into exactly this situation while testing out some error-handling logic in a class.  Here’s how I achieved it.

public static class MoqExtensions
{
    public static IReturnsResult<TMockType> Returns<TMockType, TReturnType>(this IReturns<TMockType, TReturnType> expression, params Func<TReturnType>[] results) 
        where TMockType : class
    {
        int nextResult = 0;

        return expression.Returns(() => results[nextResult++]());
    }
}

This adds a new Returns method you can use with Moq in place of one of the built-in Return methods.  It allows you to specify an arbitrary number of Func’s to be executed.  Instead of using Moq to return the Func’s directly, it creates a new Func (via a lambda expression) that will iterate over the result Func’s specified.  It does this via a closure around the results and the index of the next result.  Note that it accepts a ‘params’ array, so calling it still looks (fairly) clean:

[Test]
public void ContinuesWorkingIfErrorEventIsHandled()
{
    mResultSet.Setup(r => r.GetNextResult()).Returns((Func<IResult>)(() => { throw new NotImplementedException(); }), () => null);

    //Run...
    
    mResultSet.Verify(r => r.GetNextResult(), Times.Exactly(2));
}

That’s all there is to it!

Tags:

Feb 11 2010

Using StructureMap to provide strongly-typed access to AppSettings

Category: IoCMatt @ 10:19

I’ve been using StructureMap for the last couple of months.  I love it, and my only regret is that I didn’t start using it sooner.  I always felt like I wrote clean, testable code before, but I can see a noticeable improvement since jumping on the IoC container bandwagon. If you aren’t using an IoC container and are working on anything above a trivially simple app, you should look in to it. 

Anyway, I’m knee deep in rewriting our crawler infrastructure, and I found myself working with some classes that need access to external configuration data.  The config data is all fairly simple stuff, for example: “the path to plug-ins”, “the number of threads to use here”, “the amount of time to wait before timing out”.  We can argue about whether these things should actually be configurable outside of the code later, let’s just assume that they have to be for now.  Well, in certain configurations, our crawler pulls these settings from the app.config file.   In others, the settings are pulled from a configuration database.  That immediately means that the code can’t just reference ConfigurationManager.AppSettings, it needs to access an abstraction, we’ll call it a configuration provider.  Through the magic of IoC, all these configurable classes need to do is declare a dependency on this configuration provider, and the container will make sure they’re given whatever concrete config provider we have configured.  This is an improvement over our previous approach, where we were declaring our config provider at the top-level of the application, then passing it down, down, down the call stack to the implementations that actually needed it.  StructureMap has made things simpler, but it’s actually possible to improve things even further.

The very first version of our configuration provider abstraction looked something like this:

public interface IConfigurationProvider
{
    string this[string settingName]
    {
        get;
    }
}

Users of the provider (and by users here, I mean calling classes, not people) ended up sharing a lot of duplicate logic: extract a setting, make sure it’s there, try to convert it to the correct type, and substitute a default if all else fails.  We improved things a bit with the second version of the abstraction:

public interface IConfigurationProvider
{
    bool GetIntSetting(string name, out int holder, int defaultSetting);

    bool GetStringSetting(string name, out string holder, string defaultSetting);

    bool GetBooleanSetting(string name, out bool holder, bool defaultSetting);

    bool GetDoubleSetting(string name, out double holder, double defaultSetting);
    
    bool GetFloatSetting(string name, out float holder, float defaultSetting);
}

This is better, now callers can get their settings in a single line of code, but there was still a lot of repetitive logic across the various users.  There’s also a lot of magic strings in there.  These can be encapsulated in consts, but they’re still there.  Testing things that depend on these providers is also a little more difficult than it should be, though we do have a few classes to help. 

A better solution would not depend on strings, would remove the burden of extracting settings from the caller, and be easy to mock or replace for testing.  Perhaps something like this:

public class WidgetFactory
{
    ...
    public WidgetFactory(WidgetFactorySettings settings) 
    {
        this.Settings = settings;
    }
    ...
}

Here, my class is saying “I depend on this configuration data”, and it would be swell if the IoC container could populate it magically with the correct settings.  With just a small change, this actually becomes very easy to do:

public class WidgetFactory
{
    ...
    public WidgetFactory(IConfiguration<WidgetFactorySettings> config) 
    {
        this.Settings = config.Settings;
    }
    ...
}

The interface for the provider is quite simple:

public interface IConfiguration<TSettings> where TSettings : new()
{
    TSettings Settings { get; }
}

At run-time, the IoC container will try to find a type to satisfy this dependency.  No, you don’t have to create concrete types for everything that will ever need configuration data.  All you need is one generic type per configuration source.  Here’s a generic provider for extracting data from an app.config file:

public class AppConfigConfiguration<TSettings> : IConfiguration<TSettings> where TSettings : new()
{
    public TSettings Settings { get; private set; }

    public AppConfigConfiguration() : this(ConfigurationManager.AppSettings)
    {
    }

    //You can easily unit test this class by giving it a NameValueCollection.
    internal AppConfigConfiguration(NameValueCollection appSettings)
    {
        Settings = new TSettings();

        //Get properties we can potentially write from
        var properties = from prop in typeof (TSettings).GetProperties()
                         where prop.CanWrite
                         where prop.CanRead
                         let setting = appSettings[typeof (TSettings).Name + "." + prop.Name]
                         where setting != null
                         where TypeDescriptor.GetConverter(prop.PropertyType).CanConvertFrom(typeof (string))
                         let value = TypeDescriptor.GetConverter(prop.PropertyType).ConvertFromString(setting)
                         select new {prop, value};

        //Assign the properties.
        properties.ForEach(p => p.prop.SetValue(Settings, p.value, null));
    }
}

This provider uses a little bit of reflection and a little bit of LINQ to do it’s heavy lifting.  It grabs all the public properties off of the generic TSettings type, then scans for values matching the format “{TypeName}.{PropertyName}”.  If a match is found, and the value can be converted to the property’s concrete type, it is assigned. 

We still need to give StructureMap a little bit of direction about how to resolve the IConfiguration<TSettings> type:

ObjectFactory.Container.Configure(
    config =>
    {
        //We want to pull our configuration data from the app.config file.
        config.For(typeof (IConfiguration<>)).Use(typeof (AppConfigConfiguration<>));
    }
);

Now, anything that depends on an IConfiguration<whatever> will receive an AppConfigConfiguration<whatever>.   If we want classes to pull their configuration data from a database instead, we simply adjust our StructureMap bootstrapping.  Nothing else in the entire system has to change.

So, there you have it: a strongly-typed, generic, IoC-friendly way to handle your configuration data.  Thoughts?

Tags: