Willed and forced design

Roy Osherove, as a TypeMock employee, presents quite a dilemma from opinionated TDD blog posts simply because whether he has one or not, there’s always the question of agenda.  Which is quite unfortunate, everyone has some sort of selfish agenda at some level.  One of those posts came up in a commentary on willed and forced design, with respect to the usage of mocking frameworks:

#1 Willed Design

By writing tests, you can observe the usability of your design from a consumer perspective, and can decide whether or not you like it, and change it accordingly

#2 Forced Design

By using a subset of the available isolation frameworks(rhino, moq, nmock) or specific techniques *manual mocks and stubs) you discover cases that are not technically “mockable” or “fakeable” and use that as a sign for design change.

After about 2 seconds of playing around with dynamic languages such as Ruby and JavaScript, the idea that TypeMock is some how “impure” seemed rather silly.  Yes, it bends the CLR in crazy ways, but in and of itself, I believe it has its place.

However, I highly disagree with Roy that #2 is bad, that a tool shouldn’t force my hand in a design.  But there’s a bit of a straw man here – it’s not the tool forcing my design, it’s the test telling me where I need to change my design.  Quite simply, if I run up against something hard to test, my first choice is to isolate that piece.  Here’s an example:

public ActionResult Index()
{
    var user = Session["CurrentUser"];

    return View(user);
}

This piece is awkward to test, even though HttpSessionBase or whatever is a class with virtual methods, and it makes the test ugly.  Yes, I could mock the crap out of this heavyweight object, but that’s not really helping me out, is it?  Instead, I’ll isolate the ugly:

private readonly IUserSession _userSession;

public HomeController(IUserSession userSession)
{
    _userSession = userSession;
}

public ActionResult Index()
{
    var user = _userSession.GetUser();

    return View(user);
}

Instead of using a dictionary directly, I’ll hide that business behind a facade service, keeping the dictionary ugliness and duplication in one highly cohesive class.  But it was the _test_ that led me to do this, because I’m tuned in to pieces that are hard to mock.  File I/O?  Facade.  Web service proxies?  Facade.  Registry, HttpContext, etc. etc?  All facade.  I want to isolate my core application from the untestable pieces, not because they’re necessary untestable, but because I don’t want to couple my application directly to these external services.  Putting these behind targeted facades eliminates all that duplication that directly using these APIs tends to encourage.

There are plenty of APIs that slapping a simple facade over tends to make things worse, not better, such as:

  • Workflow Foundation
  • SharePoint

And any other framework that requires you to tiiiiightly integrate with in order to be successful.  So where does that leave me and TypeMock?  Well, I don’t use any of those frameworks that require tight coupling, and I don’t have any pain with my current tool of choice in .NET (Rhino Mocks), so why switch exactly?  For those rare occasions I might need TypeMock (DateTime.Now), I already have a solution I quite like.  Yes, TypeMock could be free, but the only compelling reason I’d switch would be to another free tool with a better, clearer to write, read and scan API.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in TDD. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://joshuaflanagan.lostechies.com/ Joshua Flanagan

    If you are willing to use the profiler API in production to the alter behavior of code, then it is fair to compare it to the flexibility that Ruby and JavaScript allow. If the extensibility is a “lie”, as it is with TypeMock, unlike with Ruby and JavaScript, I think it is perfectly valid to call it “impure”.

  • roy

    Jimmy, you present an example where you get a choice: change the design of fake what you want.,
    that is clearly #1 in my blog post. not #2.
    the case of datetime.now is clearly #2, since you DON”T get a choice.

  • http://realfiction.net Frank Quednau

    “There are plenty of APIs that slapping a simple facade over tends to make things worse, not better, such as: Workflow Foundation”

    …do you have the time to help me out with a couple of sentences what you mean by that? E.g. from the perspective of an activity, decoupling my activity code from the activityexecutioncontext does help me to test activities. Or am I on the wrong track?

  • http://isaiahperumalla.wordpress.com isaiah

    i agree with joshua, the real issue is would you use completely different underlying techiques in test and production code. For me answer is no, i would not use .net api profiler in production code.one of the key benefit of tdd is, it guides you toward designing objects that are context independent and not tied to its environment.objects tightly coupled to its environment will be difficult to instantiate in a unit test. In a context of a test, one can use type mocks magic to beak dependencies between the object under test and its environment. All this has done is made the object easier to test in isolation, but the object under test still cannot be used in another context, to me using typemocks magic simply hidden all the feedback your uni tests are providing.
    @roy i would agrue hiding dateTime inside an object would make the object context dependent, the fact that it would be hard to instantiate in the context of a test, indicates its depedency on Calendar system, time zones and locales ..

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Roy

    I would choose the same if I had to go against HttpContext.Current.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Frank

    I’m also thinking of APIs like SSIS, where you have to heavily interact with the underlying framework to get work done. If I have to use some of WF’s extension points, I’d go with something that allowed me to fake out the WF plumbing.

  • http://MurrayOn.NET/ Mike Murray

    David Tchepak (some Aussie’s blog I recently found and now really enjoy following) wrote some similar comments to yours about Roy’s blog post, but argued it from the standpoint of limitations and capabilities of the respective languages themselves (dynamic vs. static).

    It’s an interesting read: http://www.davesquared.net/2009/11/impact-of-mocking-framework-limitations.html

  • roy

    OK, just to follow through on the “language features” argument
    using dynamic proxy or IL code generation is possible but not likely.
    the only thing that fully makes sense then is using MANUAL mocks and stubs since they use directly the language features, without hiding the possible time consuming tasks behind them.

    just a thought.

    Roy.

  • http://sm-art.biz ulu

    I don’t think that using _userSession.GetUser() in a lot of places is less duplication than Session["CurrentUser"]. Unless I don’t understand the meaning of “duplication” in English.

    I do think, however, that Session["CurrentUser"] is worse in terms of encapsulation, while _userSession.GetUser() is much better in terms of code clarity..