The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








I heart FeedBurner

Latest Diggs - Programming

Computers Blogs - Blog Top Sites

Site Hits

Total: 4,900,467
since: 19 Jan 2005

Modifying the default unit tests for an ASP.NET MVC project to use Moq

posted Mon 04 May 09

When you create a new ASP.NET MVC project, one of the first things that you might notice is that you get an AccountController which takes advantage of the ASP.NET membership provider to allow your site to automatically do forms-based authentication right from the very beginning. This is a very handy feature and definitely helps get you going quickly.

The issue is that when you look at the unit tests for the AccountController, they are positively littered with manually mocked classes. I realize that this is because you don't want to make the default project template rely on a third party mocking library so in this blog post, I'm going to show how you can delete all of the manually implemented mocks for the identity, principal, membership service and forms auth service. The secret is using Moq. Moq is a lightweight mocking framework for .NET that was designed specifically for the .NET Framework 3.5 and LINQ. As such, definining mock expectations and mock return values is all done through lambdas in a ridiculously easy to read syntax, as you'll see below.

First, you want to add a reference to the Moq library. To get Moq, you can go to Moq's Google Code home page . Once you've got the Moq library on your machine, add a reference to it from your unit test project (you did choose to create a unit test project with your new ASP.NET MVC project, didn't you?). With that in place, you can replace the contents of the "GetAccountController()" method with the Moq-enabled one below:

private static AccountController GetAccountController()
{           
    var mockFormsAuth = new Mock<IFormsAuthentication>();
    var mockUser = new Mock<MembershipUser>();

    mockUser.Setup(u => u.ChangePassword(It.IsAny<string>(),
It.Is<string>(s => s == "newPass"))).Returns(true);

var mockMembership = new Mock<MembershipProvider>();
mockMembership.Setup(m => m.EnablePasswordReset).Returns(false);
mockMembership.Setup(m => m.EnablePasswordRetrieval).Returns(false);
mockMembership.Setup(m => m.MinRequiredNonAlphanumericCharacters).Returns(0);
mockMembership.Setup(m => m.MinRequiredPasswordLength).Returns(6);
    mockMembership.Setup(m => m.ValidateUser(It.IsAny<string>(),
It.Is<string>(s => s == "goodPass"))).Returns(true);
    mockMembership.Setup(m => m.GetUser(It.IsAny<string>(),
It.IsAny<bool>())).Returns(mockUser.Object);

   // Registration success mock
   MembershipCreateStatus goodStatus = MembershipCreateStatus.Success;
    mockMembership.Setup(m => m.CreateUser(It.Is<string>(s => s == "someUser"),
        It.Is<string>(s => s == "goodPass"),
        It.Is<String>(s => s == "email"), It.IsAny<string>(),
        It.IsAny<string>(),
        It.IsAny<bool>(),
        It.IsAny<object>(),
        out goodStatus)).Returns(mockUser.Object);

    // Registration failed mock (duplicate username)
    MembershipCreateStatus dupeStatus = MembershipCreateStatus.DuplicateUserName;
    mockMembership.Setup(m => m.CreateUser(It.Is<string>(s => s == "someUser"),
        It.Is<string>(s => s == "badPass"),
        It.Is<string>(s => s == "DuplicateUserName"),
        It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<object>(), out dupeStatus));

    AccountMembershipService mockService =
new AccountMembershipService(mockMembership.Object);

    AccountController controller = new AccountController(mockFormsAuth.Object, mockService);
    controller.SetFakeAuthenticatedControllerContext();
    return controller;
}

What you can then do is delete all of the manually created Mock classes. Additionally, there's a unit test that verifies whether or not the constructor has set the appropriate properties. You can remove that if you're using Unity to construct your objects (which I am, as indicated in the previous blog post).

The SetFakeAuthenticatedControllerContext() is an adaptation from one of Scott Hanselman's MvcMockHelpers.

What I like so much about this is that Moq lets me take the intent of the original code and reduce all that extra plumbing and "ceremony" and just get down to what is really important - what I want the Moq objects to provide to my objects under test. I can't imagine doing unit testing without a decent mock framework like this and again, what I like about Moq is its simplicity.

tags:            

links: digg this    del.icio.us    technorati    reddit

AddThis Social Bookmark Button




1. coofucoo left...
Wed 06 May 09 8:36 am

oh,I am sorry commt here... I am fans of you, I read your book recently. I am reading << ASP.NET E-Commerce Programming: Problem - Design - Solution>> and it helpful to my project. but I can't find the source code of this book on network. so, I find your blog hoping could get the source code . I am sorry again for my english. If you can find the code email to xyingjie@gmail.com please, thanks!


2. Web Design Pakistan left...
Thu 04 Jun 09 10:46 pm :: http://www.redsignal.biz

This is very informative and helpful


Tag Related Posts

Html.JqGrid - Cleaning up your jqGrid Code

Tue 22 Dec 09 8:46 P GMT-05
tags:              

How to Build your First Azure-Powered MVC App

Tue 29 Sep 09 2:16 P GMT-05
tags:        

ViewState is the Froo-It of the Dev-Il

Wed 23 Sep 09 3:09 P GMT-05
tags:      

Fix for Minor Bug in ASP.NET MVC New Project Template

Mon 04 May 09 2:48 A GMT-05
tags:      

NYC SharePoint Developer Needed

Mon 12 May 08 12:09 P GMT-05

Scott Guthrie Updates the ASP.NET MVC Roadmap

Wed 13 Feb 08 3:49 P GMT-05
tags:    

Volta is to Ajax what Tums is to my Stomach

Wed 30 Jan 08 4:11 P GMT-05

ASP.NET 3.5 Extensions Preview Released

Mon 10 Dec 07 2:10 P GMT-05

Microsoft unveils an MVC framework for ASP.NET

Mon 08 Oct 07 12:58 P GMT-05
tags:      

Exploring the MVC Pattern in WPF

Tue 10 Apr 07 12:51 P GMT-05
tags:                      

ASP.NET Ajax v1.0 Beta

Fri 27 Oct 06 6:17 P GMT-05
tags:      

ASP.NET vs Ruby on Rails : Round 2 (Agility)

Thu 05 Oct 06 11:02 A GMT-05
tags:                      

ASP.NET vs Ruby on Rails : Round 1

Wed 04 Oct 06 1:37 P GMT-05
tags: