Logo

Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

About the author

Maarten Balliauw is currently employed as a Technical Evangelist at JetBrains. His interests are mainly web applications developed in ASP.NET (C#) or PHP and the Windows Azure cloud platform.
More about me More about me
Send mail E-mail me


ASP.NET MVC Quickly Pro NuGet Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn
Maarten Balliauw - MVP - Most Valuable Professional
Maarten Balliauw - ASPInsider

Search

Archive

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright Maarten Balliauw 2013


ASP.NET MVC - Testing issues Q and A

WTF? When playing around with the ASP.NET MVC framework and automated tests using Rhino Mocks, you will probably find yourself close to throwing your computer trough the nearest window. Here are some common issues and answers:

Q: How to mock Request.Form?

A: When testing a controller action which expects Request.Form to be a NameValueCollection, a NullReferenceException is thrown... This is due to the fact that Request.Form is null.

Use Scott's helper classes for Rhino Mocks and add the following extension method:

public static void SetupFormParameters(this HttpRequestBase request)
{
    SetupResult.For(request.Form).Return(new NameValueCollection());
}

Q: I can't use ASP.NET Membership in my controller, every test seems to go bad...

A: To test a controller using ASP.NET Membership, you should use a little trick. First of all, add a new property to your controller class:

private MembershipProvider membershipProvider;

public MembershipProvider MembershipProviderInstance {
    get {
        if (membershipProvider == null)
        {
            membershipProvider = Membership.Provider;
        }
        return membershipProvider;
    }
    set { membershipProvider = value; }
}

By doing this, you will enable the use of a mocked membership provider. Make sure you use this property in your controller instead of the standard Membership class (i.e. MembershipProviderInstance.ValidateUser(userName, password) instead of Membership.ValidateUser(userName, password)).

Let's say you are testing a LoginController which should set an error message in the ViewData instance when authentication fails. You do this by creating a mocked MembershipProvider which is assigned to the controller. This mock object will be instructed to always shout "false" on the ValidateUser method of the MembershipProvider. Here's how:

LoginController controller = new LoginController();
var fakeViewEngine = new FakeViewEngine();
controller.ViewEngine = fakeViewEngine;

MockRepository mocks = new MockRepository();
using (mocks.Record())
{
    mocks.SetFakeControllerContext(controller);
    controller.HttpContext.Request.SetupFormParameters();

    System.Web.Security.MembershipProvider membershipProvider = mocks.DynamicMock<System.Web.Security.MembershipProvider>();
    SetupResult.For(membershipProvider.ValidateUser("", "")).IgnoreArguments().Return(false);

    controller.MembershipProviderInstance = membershipProvider;
}
using (mocks.Playback())
{
    controller.HttpContext.Request.Form.Add("Username", "");
    controller.HttpContext.Request.Form.Add("Password", "");

    controller.Authenticate();

    Assert.AreEqual("Index", fakeViewEngine.ViewContext.ViewName);
    Assert.IsNotNull(
        ((IDictionary<string, object>)fakeViewEngine.ViewContext.ViewData)["ErrorMessage"]
    );
}

More questions? Feel free to ask! I'd be happy to answer them.

kick it on DotNetKicks.com


Comments (2) -

Makka Italy |

Thursday, March 20, 2008 9:47 AM

Makka

Intresting post.
You can use a smart syntax for MembershipProviderInstance  getter Smile

get {  return membershipProvider ?? Membership.Provider; }

maartenba Belgium |

Thursday, March 20, 2008 9:53 AM

maartenba

True Smile Still too used to the "old" syntax...

Pingbacks and trackbacks (2)+

Comments are closed