Development Blog

 Thursday, March 22, 2007

In a previous post I talked about how we use automatically generated interfaces to wrap our PropertyBag's. You can also use this technique in your ViewComponents to clean up that code quite a lot. We used to have code like this:

public class SomeComponent : ViewComponent
{
  public override void Initialize()
  {
    base.Initialize();
    User user = (User)this.ComponentParams["User"];
    float value = this.Service.CalculateThatValue(user);
    this.ComponentParams["SomeCalculatedValue"] = value;
  }
}

Now we can make an interface:

public interface ISomeComponentView
{
  User User { get; set; }
  float SomeCalculatedValue { get; set; }
}

And ask the code we wrote for the PropertyBag to give us a hand in cleaning things up:

public class SomeComponent : ViewComponent
{
  public override void Initialize()
  {
    base.Initialize();
    ISomeComponentView view = this.ViewFactory.ResolveView<ISomeComponentView>(this.ComponentParams);
    float value = this.Service.CalculateThatValue(view.User);
    view.SomeCalculatedValue = value;
  }
}

Much better! If you're looking for an implementation of that ViewFactory service, Lee Henson tossed one together shortly after our post. He's also added some other, pretty nitfy features since then. Like the ability to specify a prefix with an attribute for the generated dictionary keys. As he mentions in his post, you can use it for anything (and probably should) that uses strings as keys into an IDictionary (Session, Flash, etc..). I'm planning on checking it in to CastleContrib soon, until then, grab it off the list. Thanks Lee!

by Jacob on Thursday, March 22, 2007 9:21:27 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, March 16, 2007

Last week, Aaron and I were hanging out with a bunch of the Microsoft MVP's that were up in Seattle for the MVP Summit. We had an absolute blast and got to meet some excellent developers. It was a great opportunity to get a sense for how others in our situation were handling similar problems and to share things that we have all learned along the way. We had a few beers at the Party with Palermo event and the following day a few of the guys dropped by the Eleutian Seattle offices and we threw together a podcast with Scott Hanselman. It's a very quick introduction to MonoRail for those that aren't familiar. We go on to discuss testability and IoC in the context of the Castle project. It was a great chance to expose MonoRail and the concepts behind it to a wider audience.

In no particular order, here are some blogs if you're interested in some good reading on various areas of software development:

  • Scott Bellware - Development practices, C# 3.0, Ruby, and more. His company, Dovetail, is looking into starting development using MonoRail. They are hiring.
  • Jeremy Miller - Agile, especially TDD, IoC, etc...  Jeremy wrote StructureMap, an IoC framework. So, he definitely knows the why behind a lot of the agile practices.
  • Scott Hanselman - Anything and everything development and technology. I always find something new here. I'm sure you will also.

I'm glad to see some of the news that came out of the summit. I'm sure one of us will be back to expound on them once we've done a little more research and tinkering.

by Jacob on Friday, March 16, 2007 10:56:57 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, March 01, 2007

I needed the ability to execute a task from an MsBuild project and have MsBuild keep going and not wait around on the process to exit. I was hoping to find an option on the Exec task for this but that search turned up nothing. After scowering a bit I couldn't find one somebody else wrote, so here we go:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;

using Microsoft.Build.Tasks;

namespace AsyncExec
{
  public class AsyncExec : Exec
  {
    #region Task Members
    protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
    {
      Process process = new Process();
      process.StartInfo = GetProcessStartInfo(pathToTool, commandLineCommands);
      process.Start();
      return 0;
    }
    #endregion

    #region Methods
    protected virtual ProcessStartInfo GetProcessStartInfo(string executable, string arguments)
    {
      if (arguments.Length > 0x7d00)
      {
        this.Log.LogWarningWithCodeFromResources("ToolTask.CommandTooLong", new object[] { base.GetType().Name });
      }
      ProcessStartInfo startInfo = new ProcessStartInfo(executable, arguments);
      startInfo.WindowStyle = ProcessWindowStyle.Hidden;
      startInfo.CreateNoWindow = true;
      startInfo.UseShellExecute = true;
      string workingDirectory = this.GetWorkingDirectory();
      if (workingDirectory != null)
      {
        startInfo.WorkingDirectory = workingDirectory;
      }
      StringDictionary environmentOverride = this.EnvironmentOverride;
      if (environmentOverride != null)
      {
        foreach (DictionaryEntry entry in environmentOverride)
        {
          startInfo.EnvironmentVariables.Remove(entry.Key.ToString());
          startInfo.EnvironmentVariables.Add(entry.Key.ToString(), entry.Value.ToString());
        }
      }
      return startInfo;
    }
    #endregion
  }
}

Don't fret over the WindowStyle and CreateNoWindow flags, Exec works by spawning cmd.exe with a batch file that it generates with our command. Without those flags, the command prompt window flashes by.

Obviously, very rough stuff and I make no promises of it's abilities. It worked for the simple example below and that's all I wanted. Ideally, the task would ensure the executable being started exists so we could at least fail if that's the case. But, for now this works for us. It's only used in interactive situations to spawn NCoverExplorer and things like thing. We can already easily spawn the HTML reports by using:

<Exec Command="$(ArtifactsDirectory)\mbunit-tests.html" />

But that just doesn't work when you need to run an application and not care about when it's closed:

<AsyncExec Command="$(ToolsDirectory)\NCoverExplorer\NCoverExplorer.exe $(ArtifactsDirectory)\coverage.xml" />

So here's the binaries in case somebody else is curious as well as the UsingTask.

<UsingTask AssemblyFile="AsyncExec.dll" TaskName="AsyncExec.AsyncExec" />

Obviously, if something like this is already easily possible and this was a half hour wasted, let me know. Especially if it's possible "out-of-the-box". I'm always glad to have one less dependency.

Source and Binaries

source | tools | msbuild
by Jacob on Thursday, March 01, 2007 12:52:18 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, February 27, 2007

Martin Fowler has a great post entitled Mocks Aren't Stubs. Go ahead and read/skim through that if you haven't. Of the two categories of TDDers he defines, I am definitely a mockist. That is, I almost always "use a mock for any object with interesting behavior". I do use Mocks and Stubs, but those stubs are generally just Mocks set up to be stubs (as it's easier than stubbing a class myself.) That said, I do have a few ground rules for when I write tests with Rhino Mocks that sort fall into the whole one assertion per test topic and the mocks vs. stubs thing. Here they are:

  1. Name TestMethods MethodOrPropertyName_Scenario_ExpectedResult. I stole this from someone, but I can't remember who. If you know what post that was, let me know so I can link it. An example is: CalculateCost_WhenProductIsNull_ThrowsException. I just think this makes your intent very clear and readable.
  2. Never use _mocks.Ordered() unless you are actually testing the order in which something is called... and if you are, test only that!
  3. Unless you're testing that something gets called once and only once (expensive method? caching?), use Repeat.Any(). Who cares if it gets called again?
  4. Prefer DynamicMock over CreateMock (standard mocks). Here's an example. You're testing that your controller sets FirstName on a view. You write that test and implement the feature. Two days later you need to add EmailAddress to that view, so you write your test to ensure that it is added. You implement it and run your tests... now, if you used a standard mock, your original FirstName test would fail! With a DynamicMock however, you have no tests to "fix" (tests should rarely need to be fixed because you added something to the class that has no bearing on the originally tested scenario)
  5. Don't use VerifyAll. What!?!? That's right, half the time I use Verify(someMock) and the other half I don't even Verify anything (as I can verify the result of a method called). Your tests should be complete enough that it shouldn't matter if ObjectA called ObjectB as long as ObjectA gives you the correct result.

Remember, Verification, Ordering, setting a fixed # of repeats, requiring every method/property to be "expected", etc, are all Assertions. I'm not steadfast on the whole one assertion per test thing, as sometimes a few assertions make sense. As long as you at least think about what your test would be named if you put every assertion in the method name of the test, I think that a lot of these rules would make more sense.... Would you rather diagnose a break in SomeMethod_WhenSomeObjectIsGreen_CallsFooTwiceThenCallsBarWithResultOfFoo
OnceThenSetsColorAndShapeAndResultOfFoo() or SomeMethod_WhenSomeObjectIsGreen_SetsColor()? :)

by Aaron on Tuesday, February 27, 2007 12:13:04 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Sunday, February 25, 2007

Roy Osherove brings up several good points with regards to the preached design methodology of old and the new testable design some of us have come to know and love lately.

I think that TDD really helps to eliminate a large number of these issues. If you test everything yourself, then inherently your API is testable. Unfortunately, as Jonathan Cogley points out, TDD is not yet mainstream.

A nice side effect of having a testable API or application is that often times your code is also extensible. The thing that blocks it from being fully testable and extensible are those darn sealed and internal keywords, and of course, not making things virtual that really should be. Even open source projects are guilty of not having testable or extensible enough APIs. Yes, Castle MonoRail provides AbstractMRTestCase, but that actually uses ASP.NET and is way more heavy than I like.

Here is our base class for Controller Tests. This allows you to unit test nearly every aspect of your controller, without ever hitting ASP.NET. Notice the lovely and necessary use of reflection? In order to mock the context, you'll want to call InitializeController and pass it the controller you're testing, but be sure to do it in your _mocks.Unordered block (we almost ALWAYS use mocks.Unordered... it makes tests more readable and ensures that you're tests aren't too tightly coupled with your implementation, but that's the subject for another post.)

  public class EleutianControllerTests
  {
    #region Constants
    private const string ApplicationPhysicalPath = "Q:\\PhysicalPath";
    #endregion

    #region Member Data
    protected string _virtualDirectory = String.Empty;
    protected MockRepository _mocks;
    protected IControllerServices _controllerServices;
    protected IRailsEngineContext _context;
    protected IRequest _request;
    protected IResponse _response;
    protected IServerUtility _serverUtility;
    protected IDictionary _session;
    protected Flash _flash;
    protected NameValueCollection _parameters;
    #endregion

    #region Test Setup and Teardown Methods
    [SetUp]
    public virtual void Setup()
    {
      _mocks = new MockRepository();
      _context = _mocks.CreateMock<IRailsEngineContext>();
      _request = _mocks.DynamicMock<IRequest>();
      _response = _mocks.DynamicMock<IResponse>();
      _serverUtility = _mocks.DynamicMock<IServerUtility>();
      _session = _mocks.DynamicMock<IDictionary>();
      _flash = new Flash();
      _parameters = new NameValueCollection();
    }

    protected void InitializeController(Controller controller, string areaName, string controllerName, string actionName)
    {
      BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic |
                                  BindingFlags.InvokeMethod;

      MethodInfo method = controller.GetType().GetMethod("InitializeControllerState", bindingFlags);
      method.Invoke(controller, new object[] { areaName, controllerName, actionName });

      FieldInfo field = controller.GetType().GetField("context", bindingFlags);
      field.SetValue(controller, _context);

      field = controller.GetType().GetField("serviceProvider", bindingFlags);
      field.SetValue(controller, _context);

      InitializeRailsContext(areaName, controllerName, actionName);
    }

    protected void InitializeRailsContext(string areaName, string controllerName, string actionName)
    {
      Expect.Call(_context.UrlInfo).Return(
        new UrlInfo("eleutian.com", "www", _virtualDirectory, "http", 80,
                    Path.Combine(Path.Combine(areaName, controllerName), actionName), areaName, controllerName,
                    actionName, "rails")).Repeat.Any();
      Expect.Call(_context.GetService(typeof(IUrlBuilder))).Return(new DefaultUrlBuilder()).Repeat.Any();
      Expect.Call(_context.Server).Return(_serverUtility).Repeat.Any();
      Expect.Call(_context.Flash).Return(_flash).Repeat.Any();
      Expect.Call(_context.ApplicationPath).Return("/").Repeat.Any();
      Expect.Call(_context.Request).Return(_request).Repeat.Any();
      Expect.Call(_context.Response).Return(_response).Repeat.Any();
      Expect.Call(_context.ApplicationPhysicalPath).Return(ApplicationPhysicalPath).Repeat.Any();
      Expect.Call(_request.Params).Return(_parameters).Repeat.Any();
      Expect.Call(_context.Session).Return(_session).Repeat.Any();
    }
    #endregion
  }

Oh, and back to the original point of the post. Please, please don't mark things internal or sealed unless you have a very good reason to do it. And no, I don't think that "We can't afford to support it" is a good enough reason. Also, "We're afraid the user might break something" is DEFINITELY not a good enough reason. We know what we're getting into when we extend APIs... we're all developers here.

by Aaron on Sunday, February 25, 2007 4:16:47 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Thursday, February 22, 2007

I've been writing a lot of tests lately because our code coverage isn't up to where we'd like it. NCover+NCoverExplorer is a pretty awesome and while it does have its quirks it has been incredibly useful. A lot of my adventures in writing tests is creating tons of RhinoMocks so that I can pass them to constructors and that sort of thing. So I got a strange idea, and I'm not sure how I feel about it necessarily and figured I'd propose it to all of you out there and get your thoughts.

Basically, 99% of the time in a services unit test, all the interfaces passed to the service will be mocks, so we end up with lots of functions that look like this:

[SetUp]
public void Setup()
{
  _service1 = _mocks.CreateMock<IService1>();
  _service2 = _mocks.CreateMock<IService2>();
  _service3 = _mocks.CreateMock<IService3>();
  _serviceWeAreTesting = new DefaultServiceWeAreTesting(_service1, _service2, _service3);
}

If we do this a lot for DefaultServiceWeAreTesting, it's often refactored to a single location. All in all, it can be very repetitive to create all the mocks. So, as an experiment I decided to leverage the power of the IoC container, in our case Windsor, to take care of a lot of the mundane for me. In the end I end up with this code:

[SetUp]
public void Setup()
{
  _mocks = new MockRepository();
  _container = new AutoMockingContainer(_mocks);
  _service = _container.Create<DefaultServiceWeAreTesting>();
}

AutoMockingContainer is simply a WindsorContainer with a custom facility and dependency resolver that supplies a RhinoMock for any interface that is resolved. We've also moved the setup code into a base class AutoMockingTests that has the container and mock repository. We can then write code that uses the mocks from the container:

[Test]
public void DoWork_Always_AsksOtherServices()
{
  using (_mocks.Unordered())
  {
    _container.Get<Service1>().DoWork();
    _container.Get<Service2>().DoWork();
    _container.Get<Service3>().DoWork();
  }
  _mocks.ReplayAll();
  _service.DoWork();
  _mocks.VerifyAll();
}

Of course, you don't have to always do the Get call on the container, you can do that in the Setup and use member variables, etc... the point is, the mocked services are created for us. We can also mark other types so that they aren't tested, and take advantage of the IoC and injection that we use in our application to speed up writing and maintaining tests. The implementation I've uploaded allows you to associate a particular strategy with service dependencies. They are:

  • StubbedStrategy: A mock will be created, then for each property a GetValue expectation (with Repeat.Any) will be added to return a value for that property. The value will be retrieved like any other dependency (it's strategy will be gotten, and the value from that)
  • DynamicStrategy (default): A DynamicMock will be created for the dependency.
  • StandardStrategy: A standard mock from CreateMock.
  • NonMockedStrategy: Automatically set for any service that is registered normally with the container - a standard container resolve.

So, pros and cons? To get things started:

Pros

  1. Can be easier to maintain and write tests. Adding a dependency or changing the constructor breaks tests in ways that the production environment can usually handle just fine.
  2. Automatic testing the services construction via the IoC container.

Cons

  1. Speed/peformance? Does making the container such an integral part of the test fixtures hurt performance? Setup has to be longer when we're creating the container the way we are. Does this matter? Only as long as the time saved when writing tests is larger than the time it takes to run them, which I'm sure is the case...

What do you think? So far we really like the idea, or at least think it's interesting. Here are the sources:

Source and Binaries

by Jacob on Thursday, February 22, 2007 7:04:26 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [8]  |  Trackback

I'm pleased to announce that I've committed Castle.Tools.CodeGenerator into the CastleContrib repository. What's in trunk also includes some patches posted on the mailing list by Chris Ortman and some other suggestions. It also includes some bug fixes I made. We've deleted the code generator from our repository, so any changes we make will be to the castle repository. Eleutian.Tools.CodeGenerator is no more, long live Castle.Tools.CodeGenerator!

by Jacob on Thursday, February 22, 2007 12:03:57 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, February 20, 2007

I spent yesterday and today refactoring the code for the Controller Action/View map generator tool. I made some improvements, wrote some tests and I'm pleased to announce the first release. I saw Brian had implemented his as an MsBuild task and I liked that idea, so that's how ours runs now. First, things aren't as "drop in and go" as I would like because it's still evolving in and around our, already large, code base. It's my hope that over time the tool evolves as peoples needs change, etc... we can add some more configuration, that sort of thing. I'm more than willing to hear suggestions and such. Anway, here we go...

So in order to get yourself up and running, you'll need to do a few things. First, you'll need to add the task to your MsBuild. Simply open your csproj and add the following:

<UsingTask TaskName="Eleutian.Tools.CodeGenerator.MsBuild.GenerateMonoRailSiteTreeTask" AssemblyFile="Eleutian.Tools.CodeGenerator.dll" />
<ItemGroup>
  <ViewSources Include="../YourViewsDirectory/**/*.brail">
    <InProject>false</InProject>
  </ViewSources>
</ItemGroup>
<ItemGroup>
  <ControllerSources Include="Controllers/**/*.cs">
    <InProject>false</InProject>
  </ControllerSources>
</ItemGroup>
<Target Name="BeforeBuild" Inputs="@(Compile)" Outputs="$(ProjectDir)\SiteMap.generated.cs">
  <GenerateMonoRailSiteTreeTask File="SiteMap.generated.cs" Namespace="YourNamespace.SiteMap" ControllerSources="@(ControllerSources)" ViewSources="@(ViewSources)">
  </GenerateMonoRailSiteTreeTask>
</Target>

You'll notice a few things in here. ViewSources is just the collection of view files (be it .vm or .brail, etc..). It will use the paths of those files to add the View nodes into the map. ControllerSources is the C# source files for your controllers only, specifying this helps speed up parsing. I'll get to why in a bit. And for the Sources attribute on the task you should specify all the sources in the assembly, which @(Compile) works great for.

With the task added, you should be able to build and have a SiteMap.generated.cs file, now you'll need to tweak your "base" Controller class. If you're like us, you have a Controller class that you made yourself that all of your Controller's inherit from. In that class you'll need to add some code like the following:

private ICodeGeneratorServices _services;

public ICodeGeneratorServices CodeGeneratorServices
{
  get { return _services; }
}

public RootAreaNode Site
{
  get { return new RootAreaNode(this.ControllerServices); }
}

protected virtual void PerformGeneratedInitialize()
{
  _services = new DefaultCodeGeneratorServices(
    new DefaultControllerReferenceFactory(),
    new AspDotNetRedirectService()
  );
  _services.Controller = this;
}

First is the member variable, _services. You can do this however you like, but it's consumed by the ControllerAction/ViewReference classes to do various likes. CodeGeneratorServices is a property the partial controller code uses to create the MyActions and MyViews node instances. Site is just an easy way to get the top, root level node. PerformGeneratorInitialize is overridden in the partial controller classes to add the MyViews and MyActions nodes to the PropertyBag so they are available in the views. So there you go. If I'm not missing anything, that should do the trick. Let me know if I did and I'll append to this post.

Oh, the reason for specifying the ControllerSources is to cut down on the number of classes/types we visit when generating the internal "tree" that the source code is generated from. At first glance it seems like you should just be able to parse the ControllerSources only. We coudln't really do that because we needed to gather information on the other types in the assembly so we'd be able to use them in the arguments of our actions, etc... 

I have to stress that the code is relatively new, having undergone a major refactor to isolate it from the rest of our project. I make no promises that I won't have to upload a new copy, with a fix. :)

Source and Binaries

by Jacob on Tuesday, February 20, 2007 6:36:46 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [4]  |  Trackback