Derik Whittaker

Syndication

News


Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Testing controller actions inside ASP.Net MVC

***** DISCLAIMER *****
The techniques and information here were not all thought up by me.  I got a lot of this from Scott Hanselman's screencasts, and at looking at other MVC projects.  I am only putting this into a post to have a single point of reference for the next guy.
***** END DISCLAIMER *****

One of the main goals of the new ASP.Net MVC framework is to allow for easier testing of web applications.  One of the things that is now easily testable is controller actions. 

Before we get started, there are a few things you are going to need in order to test controller actions.

  1. RhinoMocks (or any other mocking framework)
  2. The MVCMockHelper from Phil Haack
  3. A fake view Engine to use
    public class FakeViewEngine : IViewEngine
    {
        public ViewContext ViewContext { get; private set; }
    
        public void RenderView(ViewContext viewContext)
        {
            ViewContext = viewContext;
        }
    }
    

Ok, on to the actual test code.

[Test]
public void SportsEdit_Verify_Correct_Actions()
{
    // Point 1
    MockRepository mocker = new MockRepository();
    ISportService sportServiceMock = mocker.CreateMock();
    
    SportsController myController = new SportsController();
    FakeViewEngine fakeViewEngine = new FakeViewEngine();
    myController.ViewEngine = fakeViewEngine;

    // Point 2
    // Create my mock sport to be returned
    Sports sportsMock = mocker.CreateMock(new Sport {SportID = 1, Description = "Desc", Name = "Name"});

    // Point 3
    // Tell StuctureMap we want a mock, not the real thing
    ObjectFactory.InjectStub(typeof(ISportService), sportServiceMock);

    // Point 4
    // setup the expectation on my call into my service
    Expect.Call(sportServiceMock.GetSports(1)).IgnoreArguments().Return( sportsMock );

    // Point 5
    // Setup all expectations for the mocking engine
    mocker.SetFakeControllerContext(myController);
    mocker.ReplayAll();

    // Point 6            
    // call the actual controller method.
    myController.SportsDetails( 1 );

    // Point 7
    Assert.That( "SportsEdit", Is.EqualTo( fakeViewEngine.ViewContext.ViewName ) );
    Assert.That(sportsMock, Is.EqualTo(fakeViewEngine.ViewContext.ViewData));
            
}

I will break the code above into multiple sections to better explain what is going on.

  1. Here we are setting up the mock engine and creating any objects that are going to be needed during the test later.
  2. Need to create the object to return later during our expected call via our service
  3. Need to tell StructureMap what to do when someone asks for a ISportService.  In this case we want to mock it out since we DO NOT want to do a round trip.
  4. Setup the correct expectation on the mock service (needed to avoid the round trip)
  5. This is the important step, this is where we are making use of the MVCMocking helper stuff.  In here we are going to setup all sorts of mocks for later use.
    NOTE - If you forget this step you will get a NullReference exception when calling your controller
  6. Make the call into the actual controller.  This is testing the call as if it were being called by the IIS during the controller call.
  7. We are asserting that the correct view name is being called and we have passed along the correct view data as well.

I am pretty sure there are other ways to test controller actions.  In fact I have seen them.  But so far this is my favorite way.

Let me know what you think.

Till next time,


Posted 03-08-2008 11:23 AM by Derik Whittaker

[Advertisement]

Comments

Links Today (2008-03-09) wrote Links Today (2008-03-09)
on 03-09-2008 11:17 AM

Pingback from  Links Today (2008-03-09)

Dew Drop - March 9, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - March 9, 2008 | Alvin Ashcraft's Morning Dew
on 03-09-2008 3:22 PM

Pingback from  Dew Drop - March 9, 2008 | Alvin Ashcraft's Morning Dew

CodeThinked wrote Simplified Asp.net MVC Controller Testing with Moq
on 03-23-2008 1:01 AM

Simplified Asp.net MVC Controller Testing with Moq

http://devlicious.com/blogs/derik_whittaker/archive/2008/03/08/testing-controller-actions-inside-asp-net-mvc.aspx wrote http://devlicious.com/blogs/derik_whittaker/archive/2008/03/08/testing-controller-actions-inside-asp-net-mvc.aspx
on 03-28-2008 5:54 AM

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)