Site Meter
 
 

Integration Testing Your ASP.NET MVC Application

Let’s start with a quick recap:

  • Unit tests test individual software components. They supply mocks or fake versions of dependencies (such as a database) so that the unit test doesn’t rely on any external code and any failures can be pinpointed exactly. Unit testing is central to Test Driven Development – the entire TDD process is driven by unit testing.
  • Integration tests test your entire software stack working together. These tests don’t mock or fake anything (they use the real database, and real network connections) and are good at spotting if your unit-tested components aren’t working together as you expected. In general, it’s best to put most of your effort into building a solid suite of unit tests, and then adding a few integration tests for each major feature so you can detect any catastrophic incompatibilities or configuration errors before your customers do.

ASP.NET MVC famously has great support for unit testing. That’s well covered elsewhere on the web, so I won’t write more about it here. But what about integration testing?

Typically, ASP.NET MVC developers have written integration tests using a browser automation tool, such as Selenium or Microsoft’s Lightweight Test Automation Framework. These tools host a real web browser and automate a series of navigation steps, clicking on buttons and letting you write assertions about what should appear on the screen. Browser automation is fully capable of testing your JavaScript code just as easily as your business logic. However, there are also some drawbacks to browser automation:

  • Browser automation test scripts are very fragile. As soon as you alter the HTML in your views, the tests may start failing and sometimes all need to be re-recorded. Many developers are happy with browser automation at first, but after a few months are sick of re-recording the tests or maintaining thousands of lines of scripts, and give up on it.
  • Browser automation test scripts rely on parsing the generated HTML, which loses all the strongly-typed goodness of your MVC model objects.

So, how can we do integration testing without browser automation?

Introducing MvcIntegrationTestFramework

What if you could write NUnit tests (or xUnit or whatever you prefer) that directly submit a URL, query string, cookies, request headers, etc., into your application – without needing the app to be hosted in any web server but still running in the real (non-mocked) ASP.NET runtime – and get back the response text to make assertions about? In fact, what if you also got back the ActionResult (e.g., a ViewResult) that was executed, a reference to any unhandled exception it threw, and could also write assertions about cookie values or the contents of Session? What if you could string together a series of test requests to simulate a user’s browsing session, checking that a whole feature area works from end to end?

Well, my friend, all this can be yours with MvcIntegrationTestFramework :)

Download the demo project. To run the integration tests, you’ll need to install NUnit or some other test runner.

A Simple Integration Test Example

Consider the following action method:

public ActionResult Index()
{
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View();
}

You can write an integration for this using MvcIntegrationTestFramework as follows:

[Test]
public void Root_Url_Renders_Index_View()
{
    appHost.SimulateBrowsingSession(browsingSession => {
        // Request the root URL
        RequestResult result = browsingSession.ProcessRequest("/");
 
        // You can make assertions about the ActionResult...
        var viewResult = (ViewResult) result.ActionExecutedContext.Result;
        Assert.AreEqual("Index", viewResult.ViewName);
        Assert.AreEqual("Welcome to ASP.NET MVC!", viewResult.ViewData["Message"]);
 
        // ... or you can make assertions about the rendered HTML
        Assert.IsTrue(result.ResponseText.Contains("<!DOCTYPE html"));
    });
}

This is pretty similar to a typical unit test for that action method, except that you also get access to the finished rendered HTML, in case that interests you. Unlike a unit test, this integration test goes through the entire request-processing pipeline, so it tests your routing configuration, your controller factory, any dependencies your controller has, and even your view template.

Note: That doesn’t make it better than a unit test: it just solves a different problem. Unit tests are better for driving the TDD process and for proving the correctness of individual components in isolation, and they tend to be easier to maintain large volumes of over time. Integration tests, on the other hand, are good in small doses: they cover things that unit tests cannot (such as views, database connectivity, etc.) but aren’t so fine-grained as unit tests.

Integration Tests Cover End-to-end Scenarios

Consider the following sequence of behaviours:

1. When a logged-out user visits /Home/SecretAction, they should be redirected to the login screen

2. If the user then enters a valid username and password, they should be redirected back to /Home/SecretAction

3. Since the user is now logged in, they should be shown some secret information

That’s a lot of interaction between action methods, Forms Authentication, HTTP redirections, cookies, and filters. You wouldn’t typically cover that interaction in any unit test, because each of those components is a separate unit. However, if you have an end-to-end unit test that runs through the whole process, you can feel very confident that you haven’t unintentionally broken anything (e.g., by editing web.config).

Here’s a example end-to-end integration test for this whole sequence of behaviours:

[Test]
public void LogInProcess()
{
    string securedActionUrl = "/home/SecretAction";
 
    appHost.SimulateBrowsingSession(browsingSession => {
        // First try to request a secured page without being logged in
        RequestResult initialRequestResult = browsingSession.ProcessRequest(securedActionUrl);
        string loginRedirectUrl = initialRequestResult.Response.RedirectLocation;
        Assert.IsTrue(loginRedirectUrl.StartsWith("/Account/LogOn"), "Didn't redirect to logon page");
 
        // Now follow redirection to logon page
        string loginFormResponseText = browsingSession.ProcessRequest(loginRedirectUrl).ResponseText;
        string suppliedAntiForgeryToken = MvcUtils.ExtractAntiForgeryToken(loginFormResponseText);
 
        // Now post the login form, including the verification token
        RequestResult loginResult = browsingSession.ProcessRequest(loginRedirectUrl, HttpVerbs.Post, new NameValueCollection
        {
            { "username", "steve" },
            { "password", "secret" },
            { "__RequestVerificationToken", suppliedAntiForgeryToken }
        });
        string afterLoginRedirectUrl = loginResult.Response.RedirectLocation;
        Assert.AreEqual(securedActionUrl, afterLoginRedirectUrl, "Didn't redirect back to SecretAction");
 
        // Check that we can now follow the redirection back to the protected action, and are let in
        RequestResult afterLoginResult = browsingSession.ProcessRequest(securedActionUrl);
        Assert.AreEqual("Hello, you're logged in as steve", afterLoginResult.ResponseText);
    });
}

In this test, multiple requests are made as part of the same browsing session. The integration testing framework will preserve cookies (and therefore session state) from one request to the next, so you can test interaction with things like Forms Authentication and ASP.NET MVC’s AntiForgeryToken helpers. You can see this whole thing working by downloading the demo project.

This has advantages over browser automation in that (in my opinion) it’s easier to write this test – it’s concise, you don’t need to learn a browser scripting language, and you don’t need to rerecord the script if you restructure the HTML. You can make assertions at the HTML level, or you can make assertions at the ActionResult level, with fully strongly-typed access to any ViewData or Model values that were being supplied.

On the flip side, browser automation is still the only way to test your JavaScript.

Integration Testing Your Own ASP.NET MVC Application

To add these kinds of tests to your own ASP.NET MVC application, create a new class library project called MyApp.IntegrationTests or similar. Add a reference to MvcIntegrationTestFramework.dll, which you can get by downloading the demo project and compiling it, and also add a reference to your chosen unit testing framework (e.g., NUnit or xUnit).

Next, if you’re using NUnit, create a basic test fixture class as follows:

using MvcIntegrationTestFramework.Hosting;
using MvcIntegrationTestFramework.Browsing;
 
[TestFixture]
public class MyIntegrationTests
{
    // Amend this path to point to whatever folder contains your ASP.NET MVC application
    // (i.e., the folder that contains your app's main web.config file)
    private static readonly string mvcAppPath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "\\..\\..\\..\\MyMvcApplication");
    private readonly AppHost appHost = new AppHost(mvcAppPath);
}

(If you’re using something other than NUnit, amend the syntax accordingly.)

Also – and seriously you can’t skip this step – you must add a post-build step so that each time you compile, Visual Studio will copy the assemblies from your integration test project’s \bin folder into your main ASP.NET MVC application’s \bin folder. I’ll explain why this is necessary later.

image

The test fixture you just created tells MvcIntegrationTestFramework to find your ASP.NET MVC application at the specified disk location, and to host it (without using IIS or any other web server). The resulting AppHost object then provides an API for issuing requests to your application, so you could write a test as follows:

[TestFixture]
public class MyIntegrationTests
{
    // Leave rest as before
 
    [Test]
    public void HomeIndex_DemoTests()
    {
        appHost.SimulateBrowsingSession(browsingSession => {
            RequestResult result = browsingSession.ProcessRequest("home/index");
 
            // Routing config should match "home" controller
            Assert.AreEqual("home", result.ActionExecutedContext.RouteData.Values["controller"]);
 
            // Should have rendered the "index" view
            ActionResult actionResult = result.ActionExecutedContext.Result;
            Assert.IsInstanceOf(typeof(ViewResult), actionResult);
            Assert.AreEqual("index", ((ViewResult)actionResult).ViewName);
 
            // App should not have had an unhandled exception
            Assert.IsNull(result.ResultExecutedContext.Exception);
        });
    }
}

The browsingSession object lets you read and write cookies and ASP.NET session values (note: ASP.NET initializes the Session collection only after the first request in any given browsing session). The RequestResult object that comes back from ProcessRequest() lets you access the rendered response text, the actual HttpResponse object, plus the MVC ActionExecutedContext and RequestExecutedContext objects that specify what the application did in ASP.NET MVC terms.

How Does it Work Internally?

Note: if you just want to use MvcIntegrationTestFramework, you don’t need to know any of the following. I provide this info just for your interest, and to give you a head start if you want to expand the framework or change it in any way.

MvcIntegrationTestFramework uses .NET’s built-in API for creating an ASP.NET-enabled .NET appdomain and using it to host an ASP.NET application from an arbitrary disk location. The test framework then does a bunch of funky reflection-assisted stuff to attach some interceptors and event handlers to the new HTTP runtime.

When you call ProcessRequest(), internally it calls ASP.NET’s HttpRuntime.ProcessRequest() method, which invokes the request-processing pipeline. The testing framework simulates an incoming HttpWorkerRequest according to the URL, HTTP method, querystring, form values, cookies, and headers that you specify.

While the request is running, MvcIntegrationTestFramework uses its knowledge of ASP.NET MVC to add interceptors to key points in the MVC request-processing pipeline. This is how it’s able to grab and expose the ActionResult and other MVC context objects so you can make assertions about them.

Of course, all this request processing has to happen within the ASP.NET-enabled appdomain, *not* the appdomain your test runner invokes the unit test on. So, we use the slightly bizarre appHost.SimulateBrowsingSession(browsingSession => { /* your code goes here */ } syntax to shuttle your test code across the appdomain boundary and run it there. Consequently, any variables you declare outside your anonymous delegate and then use inside it *must* be serializable, or you’ll get a serialization error when they get marshalled across the appdomain boundary. This is unlikely to be a problem in real world use.

Since your test code runs in the ASP.NET-enabled appdomain, the CLR’s assembly loader will need to load your test code assembly from a location accessible to your ASP.NET MVC application. That’s why it’s necessary to have a post-build event to copy your test code assembly (and any other assemblies it references) into your ASP.NET MVC app’s \bin folder. Or you could register your test assembly in the GAC I suppose, but that’s much more hassle.

Conclusion

Personally, I find this approach to integration testing more productive than browser automation in most cases, because the tests are fast to write and are less prone to break because of trivial HTML changes. I wouldn’t want to have thousands of integration tests, though – for one thing, they’d take ages to run – but end-to-end testing for key scenarios like logging in, registering, going through shopping carts, etc., proves pretty convincingly that the major functional areas of your app are working overall, leaving unit tests to prove the fine detail of each component.

Some of the code in MvcIntegrationTestFramework was adapted from Chot’s CodeProject article, some of the ideas came from a discussion at DDD South West with Richard Fennell who’s already doing something similar except with a dependency on TypeMock, and some bits of my HttpWorkerRequest simulation code were demonstrated years ago by Phil Haack in his HttpSimulator code, which is similar to MvcIntegrationTestFramework except it predates ASP.NET MVC.

Download the demo project. To run the integration tests, you’ll need to install NUnit or some other test runner.

kick it on DotNetKicks.com

72 Responses to Integration Testing Your ASP.NET MVC Application

  1. Very interesting approach. Do you have plans to give the project a home?

  2. Interesting approach. I was recently assigned to create a web testing framework for a Webforms app. I quickly decided that recorded tests would be far too fragile — for the very reasons that you mention. Instead we built up an abstraction of the UI such that an the ID of any one HTML element is never represented in more than one place. A simple change to a UI element still breaks a lot of tests, but the fix is made in only one place. This kills a good deal of the pain of web testing, but certainly not all of it.

    Here’s an idea. A while ago I had a need to make precise assertions about blocks of HTML without knowing all the details about it. I did not want to know, and I did not care, for example, that the class attribute of a certain input tag came before or after the type attribute. Likewise, a user of MvcIntegrationTestFramework might want to know that an input tag with a certain value exists without caring where it is found in the document. Doing this type of assertion will become very painful very fast using simple string manipulation.

    Instead consider using an HTML parser and abstracting assertions behind extension methods. Here’s an example:

    http://code.google.com/p/mvccontrib/source/browse/trunk/src/MVCContrib.UnitTests/FluentHtml/Helpers/TestExtensions.cs

    This example deals with small HTML blocks as opposed to a whole document. However it’s not very hard to see how this approach might be adapted to MvcIntegrationTestFramework.

  3. Mike

    My head spins, but I think this is awesome! Indeed, the scenario where you want to test redirects after logging in, or maybe uploads and stuff like that, could really use this integrated approach.

    So how is the performance? Probably, like database integration tests, you will want to run these separately and less often?

  4. Mike

    PS. Someone give this man an MVP! ;)

  5. Interesting read!

    I don’t think there’s a drawback to using Selenium. The key issue with Selenium tests is to not write any until the HTML is finished and stable. If you create your integration tests late in a project they will be of great use. I think I’d actually prefer Selenium over your approach since I would know the entire application has been tested top to bottom.

  6. Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #367

  7. Pingback: Daily Links for Friday, June 12th, 2009

  8. Alex Simkin

    For whatever reason ActionExecutedContext and ResultExecutedContext are always null in my test.

  9. Steve

    @Eric – no particular plans – if you want to take care of it then please feel free!

    @Tim – you’re certainly right that you could perform assertions about the rendered HTML, but one of the key benefits available when testing an ASP.NET MVC app is that you can instead make strongly-typed assertions about your ViewData/Model. This eliminates much of the HTML parsing requirement.

    @Mike – this integration testing framework doesn’t add any noticeable overhead, so your tests will run as fast as your MVC app can process the requests.

    @Mats – Selenium tests (or any browser automation tests) certainly do provide even more coverage – they cover your JavaScript and your webserver in addition to your app. If Selenium is working well for you then that’s great. My personal experience has been that browser automation tests become unmaintainable over time, but I guess it depends on how much you need to change your views.

    @Alex – not sure why that would be. Does the sample project work for you? Any idea how your app differs from a standard ASP.NET MVC application to prevent the interceptors from working?

  10. I second the motion Steve Sanderson for MVP! Great post Steve.

    Roberto.-

  11. Alex Simkin

    @Steve

    It was all my fault. I was trying this under VS 2010, ASP.NET MVC 1.1 and din’t change all assembly references as needed. It works fine now and without any changes.

  12. Mike Scott

    Have you thought of integrating this with Fitnesse? Could be a killer combo…

  13. ulu

    I’ve developed a framework for in-process WebForms testing based on exactly the same principles. It’s called Ivonna (http://sm-art.biz/Ivonna.aspx). The only difference is, WebForms are much less open for extension than the MVC framework, so I had to hack the runtime using TypeMock.

    TypeMock can provide “partial integration”: e.g., you might want to run your tests against SQLite rather than MS SQL, you you can mock your database and test the integration of your view and business layer. Also, it could save some effort, e.g., you can visit a protected page without logging in.

    One problem I have is a poor performance of the very first request. I guess it’s because of the site precompilation. Have you had any problems like that?

  14. LOL dude! I separately came up with the same exact thing for a project I’m working on – even down to the lambda stuff for crossing app domains. Great minds… :-)

  15. I am currently working on a UAT/UI testing framework (not really a framework, more combining a few other libraries) integrating selenium RC and MvcContrib.FluentHtml.

    Basically im abstracting away all of the selenium calls, and using an expression based system to tie into the view model of the page under test. These expressions tie into FluentHTML making the tests and forms fully refactorable via the view model.

    Ninja

  16. Steve,

    I’m looking forward to give this a shot.
    The approach really seems more fluent and productive than browser automation.

    BTW, congrats for xVal, I really appreciate it.

  17. Steve

    @Mike Scott – I haven’t tried integrating this with Fitnesse. Although I’ve heard of Fitnesse and roughly what it does, I’ve never tried using it! If you happen to try integrating these, please let me know how it goes!

    @Ulu – I came across your Ivonna framework via http://blogs.blackmarble.co.uk/blogs/rfennell and considered using it, but unfortunately needed to avoid the dependency on TypeMock. Just like yours, my integration testing framework also takes a few seconds longer to run the first test in any given batch. This is similar to how the first request to any ASP.NET application takes a few seconds to get started, so I guess it’s a fundamental fact about how ASP.NET hosting works.

    @Andrew Peters – it’s reassuring to hear I didn’t miss some obvious way to bypass the cross-app-domain issues!

    @Dave the Ninja – cool!

    @Rafael – great, let me know how it goes. I’m most interested in whether this approach remains maintainable after writing several months worth of tests on a large project subject to frequent change, because that’s exactly the scenario I found to start getting impractical with Selenium (even though it seemed fine at first).

  18. labilbe

    Is it a good idea to embed an entire integration test inside a transaction?
    I mean, is the integration test obey to the same principles than unit test?

  19. Steve

    @labilbe – I’m not sure what transaction you’re talking about – there aren’t any transactions in this code.

    In general, integration tests don’t follow the same design principles as unit tests. For example, unit tests are supposed to test a single unit of code, decoupling it from the rest of your app, whereas integration tests don’t do any decoupling – they test the whole software stack working together.

  20. labilbe

    Sorry for my english :)
    I will try to be more concise.

    When I test my data, i embed it inside a transaction (which I rollback at the end of the test).
    So I am sure my data remains the same before and after the tests.
    This allows this to run tests over and over without having to rely on a specific order neither a number of times.

    So my idea here is to launch an integration test which at the end does not modify anything inside my database so I can repeat it any number of times.

    Is it clearer now?
    Thank you.

  21. Steve

    @labilbe – aha, I see! Thanks for clarifying. Yes, I agree that that’s a good idea. If your integration tests involve modifying a database or other persistent storage, you basically have two options:

    (1) Write some code that, before each test runs, sets up some known test data in the DB. For example, to test that a banned user can’t log in, you might create a new randomly-named banned user on the fly before running that test.

    -or-

    (2) Set up the initial conditions manually, and then keep them stable by running your tests inside transactions that you always roll back after the test run.

    Either way, it requires more work than writing a unit test, which is another reason to focus more on unit tests than integration tests. However, if you can get at least one working integration test per major feature in your app, you’ll be very well placed to detect any major config or incompatibility problems as part of your release cycle.

  22. I’d like to suggest that you copy not only the .dlls, but also the .pdbs, otherwise the stacktraces can get a bit cryptic without line information. I just spent quite a bit of time figuring that out, sadly.

  23. I built something similar a while back (though not for integration testing) and I have a suggestion for you :) . Rather than coping everything in a post process step, I wired up to the AppDomain.AssemblyResolve event. This event gets raised whenever an Assembly cannot be resolved. In my handler for AppDomain.AssemblyResolve I raise an event that crosses the AppDomain boundary back to the original AppDomain and requests the full path the the needed assembly. Once I have returned the full path to the needed assembly to the new Asp.Net AppDomain, I use Assembly.LoadFile(assemblyPath) to load the assembly.

    This has worked really well for me. Hopfully it can help make your framework even that much easier to use.

  24. Steve

    @herbrandson – great idea! In fact, since I wrote this post, I’ve expanded and improved the underlying framework in numerous ways, including loading assemblies via an AssemblyResolve callback in almost exactly the way you describe.

  25. Pingback: Servefault.com

  26. Great framework Steve, I am currently introducing it into my project and am looking at managing the assembly resolve event in a manner similar to that which you and @herbrandsom describe.

    Does your solution still require you to copy the MvcIntegrationTestFramework assembly into the web app bin dir? If not could you provide a pointer toward solving this aspect of the problem?

    Cheers and keep up the great work.

  27. This looks very interesting and I am trying it out on my current project but one thing I cannot figure out is how to debug. Breakpoints which I set in the code do not get hit, though I am attaching to both the NUnit process and the w3p.exe process as well. Any ideas?

  28. Steve

    Hi Ken

    I’m surprised the debugger isn’t working for you. The ASP.NET appdomain is running inside the NUnit GUI process, so if you attach the debugger to that it should hit your breakpoints (assuming you’ve compiled in debug mode, of course). It certainly does work for me :)

  29. Great stuff! Thanks for all the hard work. Now I’ll start with the easy bits.

  30. Rohit

    Hi Steve,
    I liked the idea, and was looking for similar solution for testing my views, It’s really great that you have done the hard part! Thanks for it.
    Now, there is another problem that I am facing, some of views in my application are dependent upon the the model object, they generate form fields using the model data(for example Edit pages). I want to mock the model object and pass it to the request processor so that it can pass to view engine and in last my views can render the required fields.

    In essence I want to test that my required form fields exists in the view when its rendered and am going to use those form fields to post to another action to test the model binding is actually working as intended.

    I can test under and over posting with existing solution by passing form fields manually.

    Any help would be greatly appreciated.

  31. Rohit

    Continuing from last post…. I realized that I can use dependency injection to create fake/real models.
    Now my question is how can I create two config files for web application one for hosting in IIS and one for hosting in testing framework?

  32. Steve

    Rohit, if you use the mechanism I’ve provided with this blog post, you’ll be doing an integration test that covers your whole application stack, including view rendering, model binding, and validation. I don’t think you’ll need to create fake models, and I’m not sure how you’d use dependency injection to do that anyway.

  33. Norman

    Excellent, but when accessing the Response.Headers I get a System.PlatformNotSupportedException “This operation requires IIS integrated pipeline mode.”

    appHost.SimulateBrowsingSession(sess =>
    {
    RequestResult r = sess.ProcessRequest(“test”);

    Assert.AreEqual(“value”, r.Response.Headers.Get(“key”));

    });

    How to enable this in Cassini? Testing the response headers are important for this project as the MVC application is a REST style web service.

  34. Pingback: Deleporter: Cross-Process Code Injection for ASP.NET « Steve Sanderson’s blog

  35. Jesus Garza

    Steve, is the demo project updated for mvc 2? You commented that you improved the framework. Are you publishing it?

    Thanks and best regards.

  36. Jesus Garza

    Ok, i tested against mvc 2 and though the demo doesn’t work, the MvcIntegrationTestFramework does.

  37. @Mats
    “until the HTML is finished ”
    I have yet to make a website where the html is finished.

  38. Ben

    Hi Steve,

    I’ve just started poking around with this. Awesome stuff. However, I’d like to wire it up with SpecFlow… to properly do that, I’d like the RequestResult to hang around after the call into SimulateBrowsingSession. Possible or am I better off just copying the text and status code back to local variables?

  39. Johan

    Hey! Great article!

    Trying to get this to work with tfs without luck. The problem I have is: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (3717): The command “copy “C:\Builds\1\Project X\Project X CI\Binaries\*.dll” “C:\Builds\1\Project X\Project X CI\Binaries\..\..\..\TT.Web\bin\”" exited with code 1.

    Anyone know what’s wrong?
    Thanks in advance

  40. Simply Wonderful! Very useful to our development and fits our testing needs at the moment!

  41. Aaron

    what if your integration testing connection string to the db needs to be different? as i see it it uses the web.config from the web project not the app.config from the test project. is there any way around this?

  42. Thanks for the information. You have done wonderful work communicating your message. Keep up the great job.

  43. Lucian

    Great job Steve, it worked OK from the first attempt.

    Thanks a lot,
    Lucian

  44. chidi

    I cant for the life of me get this working, I get an error on the line

    private readonly AppHost appHost = new AppHost(mvcAppPath);
    with the mesage

    System.IO.FileNotFoundException : Could not load file or assembly ‘Remotion.Data.Linq, Version=1.13.41.2, Culture=neutral, PublicKeyToken=cab60358ab4081ea’ or one of its dependencies. The system cannot find the file specified.

    An unhandled System.AppDomainUnloadedException was thrown while executing this test : Attempted to access an unloaded AppDomain.

  45. chidi

    Update

    after digging further I can see that this fails on the line

    private static void AttachTestControllerDescriptorsForAllControllers()
    {
    var allControllerTypes = from assembly in AppDomain.CurrentDomain.GetAssemblies()
    from type in assembly.GetTypes()
    where typeof (IController).IsAssignableFrom(type)
    select type;
    foreach (var controllerType in allControllerTypes)
    InterceptionFilter.AssociateWithControllerType(controllerType);
    }

    line —– from type in assembly.GetTypes()
    where the assembly
    assembly = {NHibernate, Version=3.0.0.1001, Culture=neutral, PublicKeyToken=aa95f207798dfdb4}

    the loader exceptions contain the message + [0] {“Could not load file or assembly ‘Remotion.Data.Linq, Version=1.13.41.2, Culture=neutral, PublicKeyToken=cab60358ab4081ea’ or one of its dependencies. The system cannot find the file specified.”:”Remotion.Data.Linq, Version=1.13.41.2, Culture=neutral, PublicKeyToken=cab60358ab4081ea”} System.Exception {System.IO.FileNotFoundException}

  46. chidi

    Im assuming this framework may have issue working with the latest version of Nhibernate? I need a helping hand here Steve

  47. IRON

    @Aaron: the same issue. One of possible solutions is:

    1. You create separate web.config for test purposes. Set up there all necessary info.
    2. Before running tests replace original config file with test one.
    3. After tests are compete – replace it back with original one.

  48. Tyson

    @chidi – I had a similar issue. I wrote a small method to safely retrieve Types from the assembly (altered the code).

    Currently, I’m having issues using a web.config that is set for IIS 7 deployment work with the tests.

  49. chidi

    @ Tyson, yeah I had to modify the code to ignore those assemblies that were causing issues, Nhibernate being one of them, it worked after that.

  50. Alexander Nyquist

    BrowsingSession.Session has no setter, and the constructor does not initialize it.

    How can i provide session data to ProcessRequest?

    Thanks Alexander

  51. Pingback: MvcIntegrationTestFramework or an alternative updated for ASP.NET MVC 3 | DeveloperQuestion.com

  52. Can you tell me where you got the news for this post?

  53. Pingback: Buzz Lightyear is here » Blog Archive » links for 2011-01-11

  54. Do you guys have a twitter fan page for Integration Testing Your ASP.NET MVC Application «
    Steve Sanderson’s blog? I looked for one on the internet but could not see one, I would really like to become your fan!

  55. Pingback: MVCIntegrationTestFramework | Нанокодинг – кодим по немногу

  56. Another thing is that when searching for a good internet electronics store, look for web stores that are continuously updated, always keeping up-to-date with the newest products, the most beneficial deals, and also helpful information on products and services. This will ensure that you are doing business with a shop which stays on top of the competition and provide you what you need to make intelligent, well-informed electronics buys. Thanks for the vital tips I have really learned through the blog.

  57. Richard Forrest

    Hi Steve
    Any chance you wanna put this into a nuget package. Possibly including the post build event.

  58. Mosh

    Hi Steve,

    Great tool! Well done. However, I have a problem with tests that involve modifying the database. I wrap these tests with a TransactionScope but it doesn’t seem to be working. Any ideas? Is this because the actions are executed in a different AppDomain?

    Any advice would be greatly appreciated.

    Cheers,
    Mosh

  59. Mosh

    Also, my tests take ages to execute (roughly around 20 seconds)!! None of these actions are slow. When I run them manually by browsing the site, they are executed in a second max! What could be wrong here?

  60. Quirijn Slings

    This framework looks really promising. The ResponseText works great, that is something I was never able to test with other frameworks! However, I have the same problem as one of the other commenters: the ActionExecutedContext and ResultExecutedContext are always null.
    What am I doing wrong?
    I’m using the ‘my first mvc’ HomeController + Index action.

  61. Quirijn Slings

    One thing I forgot: I’m using MVC 3.0, and had to replace the reference to System.Web.Mvc before I could use the framework. Could that be the problem?

  62. I just cant believe it has happened. I knew he was ill, and i knew it was of Pancreatic Cancer which is more or less incurable, but for it to happen is still a shock. I did actually, for a split second, think that when he stepped down from CEO that that was it for him and he was not long away, but never for a second wanted to believe that. Such an inspirational person and one the whole world will miss. I am unbelievably sad right now. Rest in Peace Steve.

  63. My hubby and I arrived here simply because this particular webpage had been tweeted by a woman I had been following and am pleased I made it here.

  64. Somesh Batra

    Very informative post. It’s really helpful for me and helped me lot to complete my task. Thanks for sharing with us. I had found another nice post over the internet which was also explained very well about How to read and write Cookies in asp.Net, for more details of this post check out this link…

    http://mindstick.com/Articles/60de760f-be8e-4ad8-8ec8-207aef746ea1/?How%20to%20read%20and%20write%20Cookies%20in%20ASP.Net

    Thanks

  65. A thoughtful opinion and tips I’ll use on my web-site. Youve obviously spent some time on this. Nicely performed! Regards http://www.platosoul.com/band/oldcalendar/calendar.pl?ACTION=VIEWDAY&Year=2010&Month=4&Date=1

  66. Spot on with this write-up, I truly suppose this website needs way more consideration. I’ll probably be again to read way more, thanks for that info.

  67. Amazing write-up shows you the low down of USB Card Reader in addition to the reasons why you need to take action straight away. This is the USB Card Reader truth your Parents doesn’t want one to know! Up grade your USB Card Reader in half the time without spending additional cash!

  68. Peter

    I can’t get this to run. When I execute a very simple test all I get is this:

    Unable to create instance of class website.tests.UnitTest1. Error: System.InvalidOperationException: Could not load MvcIntegrationTestFramework.dll within a bin directory under C:\[path]\Website. Is this the path to your ASP.NET MVC application, and have you set up a post-build event to copy your test assemblies and their dependencies to this folder? See the demo project for an example..

    It is the correct path to the MVC application and I’ve put the test project beside it in the solution. I’ve also set up the post-build copy string and it copies the .dll files which I verify by looking in the MVC apps bin folder. Still it claims it can’t find the MvcIntegrationTestFramework.dll

    I’m using MSTest as test framework

    Does anyone know how to solve this?

  69. It’s a pity you don’t have a donate button! I’d definitely donate to this brilliant blog! I guess for now i’ll settle for bookmarking and adding your RSS feed to my Google account. I look forward to brand new updates and will talk about this website with my Facebook group. Chat soon!