4

I’m just learning ASP.NET MVC and I’m trying to create a mock form request for a unit test.

I’m using RhinoMocks.

I have looked at the following websites but cannot get these to work.

http://blog.maartenballiauw.be/post/2008/03/19/ASPNET-MVC-Testing-issues-Q-and-A.aspx

Update: Controller Code:

    /// <summary>
    /// Creates a new entry
    /// </summary>
    /// <returns></returns>
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind()]Person person) 
    {
        if (Request.Form["DateOfBirth"].ToString() == "")
        {
            TempData["message"] = "Please select a date of Birth";
            ViewData["DateOfBirth"] = Request.Form["DateOfBirth"].ToString();

            MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState, person.ValidationMessages);
            return View();
        }
        else
        { 

        if (person.IsValid())
        {
            person.DateOfBirth = Convert.ToDateTime(Request.Form["DateOfBirth"]);

            personRepository.SaveOrUpdate(person);
            TempData["message"] = person.Firstname + " was successfully added";
            return RedirectToAction("Create", "OrderDetails", new { id = person.ID });
        }
        else
        {

            ViewData["DateOfBirth"] = Request.Form["DateOfBirth"].ToString();

            MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState, person.ValidationMessages);
            return View();
        }

        }

    }

3 Answers 3

3

If you change the action method to have a FormCollection as the final parameter you can then pass in a FormCollection instance that contains all your values. The MVC framework will automatically pass in the values from the form within that parameter when running live.

public ActionResult MyMethod(FormCollection form)
{
    // in testing you will pass in a populated FormCollection object
    // at runtime the framework will populate the form parameter with
    // the contents of the posted form
}

Here is a reasonable example of it being used.

Edit

Have you tried this:

    /// <summary>
    /// Creates a new entry
    /// </summary>
    /// <returns></returns>
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind()]Person person, FormCollection form) 
    {
        if (form["DateOfBirth"].ToString() == "")
        {
            TempData["message"] = "Please select a date of Birth";
            ViewData["DateOfBirth"] = form["DateOfBirth"].ToString();

            MvcValidationAdapter.TransferValidationMessagesTo(
                ViewData.ModelState, person.ValidationMessages);
            return View();
        }
        else
        { 

        if (person.IsValid())
        {
            person.DateOfBirth = Convert.ToDateTime(form["DateOfBirth"]);

            personRepository.SaveOrUpdate(person);
            TempData["message"] = 
                person.Firstname + " was successfully added";
            return RedirectToAction(
                "Create", "OrderDetails", new { id = person.ID });
        }
        else
        {

            ViewData["DateOfBirth"] = form["DateOfBirth"].ToString();

            MvcValidationAdapter.TransferValidationMessagesTo(
                ViewData.ModelState, person.ValidationMessages);
            return View();
        }

        }

    }
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I still cannot get this to work. Is there any other examples?
Any chance of editing your question with some code? The action method and your test code perhaps?
2

You can also mock the form and I suggest you take a look at http://mvccontrib.codeplex.com/:

var form = new NameValueCollection(); form.Add("publish", "true"); _controller.Request.Stub(x => x.Form).IgnoreArguments().Return(form);

1 Comment

how did you initialize _controller?
1

Unless you're testing MVC itself, shouldn't you be mainly testing that the controller's action does the right thing with the arguments passed by the framework?

You can probably mock more indirect form access via:

controller.ActionInvoker.InvokeAction(ctx);

where ctx is a ControllerContext, with the form data etc. Here's an example using rhino to provide the context (MoQ also shown).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.