Integrating MVC Application Testing without Pain in UI Automation

I am starting to develop a new MVC application that will be mostly written using TDD. I would like to add some integration tests to ensure that the fully wired application (I am using StructureMap for IOC, NHibernate for persistence) works as expected.

While I intend to write some functional smoke tests using Selenium, for the sake of maintainability I would prefer to run most of the integration tests by directly invoking actions on my controllers using good old C #.

There are surprisingly few indications of how this could be done, so I hit the attack plan

  • Pull all the bootstrap code from Global.asax and into a separate class
  • Trying to use MvcContrib-TestHelper or similar to create ASP.NET dependencies (Context, Request, etc.)

I followed step 1 but actually have no idea how to proceed to step 2. Any guidance would be appreciated.

public class Bootstrapper
{              
    public static void Bootstrap()
    {
        DependencyResolverInitializer.Initialize();
        FilterConfig.RegisterFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        ModelBinders.Binders.DefaultBinder = new SharpModelBinder();
    }           
}

public class DependencyResolverInitializer
{
    public static Container Initialize()
    {
        var container = new Container();
        container.Configure(x => x.Scan(y =>
        {
            y.Assembly(typeof(Webmin.UI.FilterConfig).Assembly);
            y.WithDefaultConventions();
            y.LookForRegistries();

        }));

        DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
        return container;
    }
}

public class StructureMapDependencyResolver : IDependencyResolver
{
    private readonly IContainer _container;

    public StructureMapDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        if (serviceType.IsAbstract || serviceType.IsInterface) {
            return _container.TryGetInstance(serviceType);
        }
        return _container.GetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }
}

      

+3


source to share


1 answer


If you want to do automated end-to-end testing of an ASP.NET MVC application without going through the UI, one good way to do this is to programmatically send HTTP requests to different URLs and assert the state thereafter.

Your integration tests will look like this:

  • Arrange: Launch a web server to host the web application under test.
  • Act: Send an HTTP request to a specific url to be processed by a controller action
  • Assert: Check the system state (for example, find specific database records) or check the response content (for example, look for specific lines in the returned HTML)

You can easily host your ASP.NET web application on the embedded web server using CassiniDev . Also, one convenient way to send HTTP requests is by using the Microsoft ASP.NET Web API client libraries .



Here's an example:

[TestFixture]
public class When_retrieving_a_customer
{
    private CassiniDevServer server;
    private HttpClient client;

    [SetUp]        
    public void Init()
    {
        // Arrange
        server = new CassiniDevServer();
        server.StartServer("..\relative\path\to\webapp", 80, "/", "localhost");
        client = new HttpClient { BaseAddress = "http://localhost" };
    }

    [TearDown]
    public void Cleanup()
    {
        server.StopServer();
        server.Dispose();
    }

    [Test]
    public void Should_return_a_view_containing_the_specified_customer_id()
    {
        // Act
        var response = client.GetAsync("customers/123").Result;

        // Assert
        Assert.Contains("123", response.Content.ReadAsStringAsync().Result);
    }
}

      

If you're looking for a more complete example of this technique in action, you can find it in the MVC 4 Web Application Sample, where I demonstrated it in the context of writing automated acceptance tests .

+4


source







All Articles