MicroController Pattern

From time to time there is a need to use functionality that is encapsulated in graphical components from a regular class or view-model. E.g. you might need the coordinates of the mouse cursor relative to a certain control.

One problem with that is: How can you run automated tests against that view-model? Using UI components in standard unit tests is usually not a good idea.

MicroControllers are a variation of the Adapter pattern. They wrap real UI components and forward only the parts of the component that are needed.

To pick up the above example: If you need the position of the mouse relative to a WPF Canvas you could do something like this.

public abstract class Surface
{
  public abstract Point GetMousePositionOnSurface();
  public abstract Point GetAbsoluteMousePosition();
}

An implementation that wraps the canvas can look like this:

public class CanvasSurface : Surface
{
  private readonly Canvas canvas;
  public CanvasSurface(Canvas canvas)
  {
    Guard.AssertNotNull(canvas, "canvas");
    this.canvas = canvas;
  }
  public override Point GetMousePositionOnSurface()
  {
    return Mouse.GetPosition(this.canvas);
  }
  public override Point GetAbsoluteMousePosition()
  {
    var relative = Mouse.GetPosition(this.canvas);
    var absolute = this.canvas.PointToScreen(relative);
    return absolute;
  }
}

And all of a sudden you can not only use the framework functionality baked into Canvas but also run automated tests using POCO test-doubles of Surface that return canned results.

public class MockSurface : Surface
{
  public override Point GetMousePositionOnSurface()
  {
    return new Point();
  }
  [...]
}

public class MyViewModel
{
  private readonly Surface surface;
  public MyViewModel(Surface surface)
  {
    this.surface = surface;
  }
  public double CalculateDistanceToMousePointer()
  {
    Point p1 = this.surface.GetMousePositionOnSurface();
    [...]
    return distance;
  }
}

Last edited Dec 23, 2011 at 11:17 AM by weberse, version 4

Comments

No comments yet.