Gray's Matter
Justice Gray - North America's favorite metrosexual software consultant

I Wish These People Updated More Than Once a Year

*


Apologies for the technical interruption - we'll get back to our regular lack of content soon enough - but I was reading over Ben Scheirman's post on testing TempData and my comment ended up just long enough that I thought it needed its own post.


One of the current projects I am working on is using the Microsoft MVC.  Now, I haven't been screwing with TempData like Ben (haven't had the need) but I *had* previously encountered similar issues with Request.Form.  Sure, there's no problem with mocking out IHttpContext and all of its 15 million dependencies therein, but
a) I'm pretty married to the mockRepository.Record(){}/mockRepository.Playback(){} syntax
b) it just seemed like a lot of extra code to get at a NameValueCollection.

Hence, I just busted out layer supertype and had a base class with the following pertinent data:

public class MyControllerBase: Controller
{
    public virtual NameValueCollection FormData
    {
            get
            {
                return Request.Form;       
            }
    }
}

Methods in the inheriting controllers refer to FormData instead of Request.Form in exactly the same way.  Let's take a small piece of code from the Igloo of Love application that we'll talk about at a later date...

e.g. Request.Form["lastnameofdonaldsnewlovah"]
becomes FormData["lastnameofdonaldsnewlovah"]

(Note: yes, this is really just an example of utilizing a base class with a testing hook but I prefer dropping "layer supertype" as using larger words == instant credibility).

Now, the reason I do this is because when I need to set up some form values for testing, I want it to be even simpler than with the mocking of IHttpContext, ya da ya da...

thus, in test controller classes (yes, this is testing by inheritance and many of you would rather scrape your nether regions with a board full of nails, but bear with me please) we do the following:

private NameValueCollection privateFormData;
 
public override NameValueCollection FormData
{
    get
    {
        return privateFormData;
    }
}

Now, this makes some of my testing RIDICULOUSLY EASY, because all I need to do in my test is write:

myTestController.FormData["lastnameofdonaldsnewlovah"] = "Bellware";

and we're set to test actions that rely on FormData.

When I first read Ben's post, my initial thought was "Well, why don't we just extend my layer supertype (good job, Justice, remember that term when negotiating salary in the future) to also 'mock' TempData?"

My second thought was

"public TempDataDictionary(IHttpContext httpContext)
{
    if (httpContext == null)
    {
        throw new ArgumentNullException("httpContext");
    }
    this.HttpContext = httpContext;
    this.EnsureReadData();
}"

Yes, for those of you asking, I think in Reflector disassembled code, which I am 7331*. 

Third thought was, "Well, this certainly sucks, I'm going to kill myself now."

After the depression phase of my manic depression subsided, I'm back on the "manic" phase to tell you that
no testing hook for TempData == SUPER CRAZY, and since
it seems I have already successfully taken on 2/3rds of the Microsoft MVC team, I would like to extend a challenge to Phil Haack: for the love of all that is good, please fix this so I don't need to jump through five flaming hoops and castrate a lion in order to mock out TempData!

Since  
I mean, take a look at all the efforts poor Ben has to go through in order to get this going with mocks!  Yike!

I've got your back Ben!!  That's what blood brothers do!!

* Yes, this image shows up when searching Google for TempData, confirming the theory I espoused at my presentation on DevTeach 2007 that using the MS MVC is the only guarantee a .NET developer has for getting LAID**.
** Unless of course you are as good looking as yours truly*** in which case you should be getting some in between every unit test you write
*** Unfortunately, that's impossible

Thursday, January 31, 2008 #