Tim Scott's Blog

May 31, 2009

Reusable “Should” Extensions

Filed under: Test Driven Development, Unit Testing — Tim Scott @ 4:06 am

Should Extensions

UPDATE (6/9/09): Get the code here.

Some months ago I started wrapping my test asserts in fluent “should” extensions, like this:

public static T ShouldEqual<T>(this T actual, T expected)
{
    Assert.AreEqual(expected, actual);
    return actual;
}

Some of these extensions do a little more than just wrap assertions, for example:

public static T ShouldContainOne<T>(this IEnumerable<T> e, Func<T, bool> predicate)
{
    var match = e.ShouldContainAtLeastOne(predicate);
    if (match.Count() != 1)
    {
        Assert.Fail("Expecting 1 matching item.  Found {0}.", match.Count());
    }
    return match.First();
}

Reuse Dilemma

I put these extension methods in a static class in a helper project for re-use across test projects within the application.  Then one day I began work on a new application for a new client.  I love my “should” extensions and felt I could not live without them. Cut-and-paste to the rescue. Yuck. Now I am on to another application. Cut-and-paste again. Get me off this merry-go-round!

I considered creating a common assembly to share across my projects. However, as a consultant I prefer not to leave behind binary bits with this client and that client.

Making matters worse, the aforementioned applications do not all use the same testing framework.

Solution

So I have started developing a library of reusable “should” extensions that I am planning to release as open source – tentatively named “ShouldIt.” It will plug-and-play with all the major unit testing frameworks – with zero configuration using MEF.  To use it, with NUnit for example, you will reference ShouldIt.Core, ShouldIt.Clr and ShouldIt.NUnit in your test project.

You might be wondering, what is ShouldIt.Clr, and why is it separate from ShouldIt.Core?  ShouldIt.Clr will provide extensions to the CLR base class library types.  This leaves room to add, for example, ShouldIt.Watin.

By the way I considered writing my own assertions instead of wrapping those provided by the testing framework.  Then I opened NUnit and MbUnit in Reflector.  Whew!  There’s a lot more to those simple-looking assertions than I had expected.

Challenges And Questions

The biggest challenge I foresee is managing multiple binary dependencies to the testing frameworks.  This is mitigated by the fact that references will not be version specific.  Hence, pain will only be felt when the Assert APIs, more specifically those methods that ShouldIt calls, are changed.  I expect that those APIs are fairly stable.  That said, we can expect major releases to have breaking changes, as we have seen recently with MbUnit 3 (Gallio).

My questions for you:

  1. Anyone else feeling this pain?
  2. Has someone solved this already and I just have not seen it?
  3. Can you think of a better name than “ShouldIt?”

May 18, 2009

Use MvcContrib.FluentHtml With Spark View Engine

Filed under: FluentHtml, MS MVC, Spark View Engine — Tim Scott @ 11:04 pm

Introduction

MvcContrib.FluentHtml is a library of extensible HTML helpers for MS MVC.  It works out of the box with the WebForms view engine. As it turns out, it’s not very hard to use with other view engines.  Read on to see how to use FluentHtml with the Spark view engine.

View Class

First, you need to add a class to your project, something like this:

public abstract class SparkModelViewPage<T> : SparkView<T>, IViewModelContainer<T> where T : class
{
    private readonly List<IBehaviorMarker> behaviors = new List<IBehaviorMarker>();

    protected SparkModelViewPage()
    {
        behaviors.Add(new ValidationBehavior(() => ViewData.ModelState));
        //add any other desired behaviors here
    }

    public string HtmlNamePrefix { get; set; }

    public T ViewModel
    {
        get { return Model; }
    }

    public IEnumerable<IBehaviorMarker> Behaviors
    {
        get { return behaviors; }
    }
}

NOTE: I updated this class since the original post. I removed constructors overrides that pass in behaviors ad htlmPrefix. You don’t need these unless you expect to further derive this class.

Configuration

Then apply a little configuration – either in the config file or in code. Refer to the Spark config documentation for details.

var settings = new SparkSettings()
    .SetPageBaseType("SparkModelViewPage")
    .AddAssembly("MvcContrib.FluentHtml")
    .AddNamespace("MvcContrib.FluentHtml")
    ...yadda yadda;
ViewEngines.Engines.Add(new SparkViewFactory(settings));

PageBaseType tells the Spark view engine to use your new class as the base class for all views.  The other two settings tell the Spark view engine to use FluentHtml in views.

Usage

That’s it.  Then you can use FluentHtml in your views like so:

<viewdata model="MyApp.Models.Person"/>  

<%=this.TextBox(x => x.FirstName).Label("First Name") %>
<%=this.TextBox(x => x.LastName).Label("Last Name") %>

Conclusion

I should add one caveat. I have tested only the most naive scenarios, and I have not used Spark for any production work at all. Please comment on any issues you encounter in using FluentHtml with Spark.

Create a free website or blog at WordPress.com.