Eddy Kavanagh
Eddy Kavanagh

Reputation: 254

Avoiding missing views in ASP.NET MVC

When testing an ASP.NET MVC 2 application I hit a problem when a view could not be located.

Looking at the code I realised that the aspx file for the view had not been added to the source control repository. On this project that's quite easy to do as we use StarTeam for source control and it doesn't show new folders when checking in. This view was for a new controller and so a new folder was created for it and it was therefore missed.

Our build server (using Hudson/MSBuild) didn't pick up on this, as the code still builds fine with the aspx file missing. Our controller unit tests test the ActionResults which obviously still pass without the view there.

This got picked up in system testing but how can I catch this earlier (ideally on the build server).

Thanks in advance

Upvotes: 4

Views: 319

Answers (3)

Rosdi Kasim
Rosdi Kasim

Reputation: 25966

This is an old question, but if anyone still looking for this you ought to try SpecsFor.Mvc by Matt Honeycutt.

Not only it can be used to make sure the Views are properly included/added in the source control, it can even do integration test to make sure those Views are valid.

Link to its website: http://specsfor.com/SpecsForMvc/default.cshtml

Link to the nuget package: https://www.nuget.org/packages/SpecsFor.Mvc/

Link to github: https://github.com/MattHoneycutt/SpecsFor

Here is a code snippet taken from the website showing how to use it.

public class UserRegistrationSpecs
{
    public class when_a_new_user_registers : SpecsFor<MvcWebApp>
    {
        protected override void Given()
        {
            SUT.NavigateTo<AccountController>(c => c.Register());
        }

        protected override void When()
        {
            SUT.FindFormFor<RegisterModel>()
                .Field(m => m.Email).SetValueTo("[email protected]")
                .Field(m => m.UserName).SetValueTo("Test User")
                .Field(m => m.Password).SetValueTo("P@ssword!")
                .Field(m => m.ConfirmPassword).SetValueTo("P@ssword!")
                .Submit();
        }

        [Test]
        public void then_it_redirects_to_the_home_page()
        {
            SUT.Route.ShouldMapTo<HomeController>(c => c.Index());
        }

        [Test]
        public void then_it_sends_the_user_an_email()
        {
            SUT.Mailbox().MailMessages.Count().ShouldEqual(1);
        }

        [Test]
        public void then_it_sends_to_the_right_address()
        {
            SUT.Mailbox().MailMessages[0].To[0].Address.ShouldEqual("[email protected]");
        }

        [Test]
        public void then_it_comes_from_the_expected_address()
        {
            SUT.Mailbox().MailMessages[0].From.Address.ShouldEqual("[email protected]");
        }
    }
} 

Upvotes: 0

Doug Porter
Doug Porter

Reputation: 7887

What version of StarTeam are you running? In StarTeam 2008 (not sure when this feature was first added) within a selected project/view, you can select from the menu Folder Tree->Show Not-In-View Folders. This will show folders you have on local disk that have not been added to the project (they will appear with the folder icon colored white).

Upvotes: 1

Joel Martinez
Joel Martinez

Reputation: 47749

You can write unit tests that test the actual view, and then if the unit test doesn't pass on the build server, you know you have a problem. To do this, you can use a framework such as this:
http://blog.stevensanderson.com/2009/06/11/integration-testing-your-aspnet-mvc-application/

With this you can write unit tests such as this (from the post)

[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"));
    });
}

Upvotes: 2

Related Questions