Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock MVC form POST with Moq

Could anyone please tell how to mock a MVC form post using Moq?

All I want is to unit test my method based on few different form posts.

I tried to Google for this and there isn't a top to bottom guide out there.

Thanks

EDIT: adding code

    [TestMethod]
    public void SubscriptionControllerTest()
    {
        var subscriptionViewModel = new SubscriptionViewModel();

        //HTTP REQUEST SET UP
        var httpRequest = new Mock<HttpRequestBase>();

        httpRequest.Setup(r => r.Path).Returns("/Subscription/SendEmail");

        httpRequest.Setup(r => r.Form).Returns(delegate()
        {
            var nv = new NameValueCollection();
            nv.Add("FirstName", "John");
            nv.Add("LastName", "Smith");
            nv.Add("Email", "[email protected]");
            nv.Add("Comments", "Comments are here...");
            nv.Add("ReceiveUpdates", "true");
            return nv;
        });


        //HTTP CONTEXT SET UP
        var httpContext = new Mock<HttpContextBase>();

        httpContext.Setup(c => c.Request).Returns(httpRequest.Object);

        var subscriptionController = new Mock<SubscriptionController>();
        subscriptionController.Setup(s => s.HttpContext).Returns(httpContext.Object);

        var result = subscriptionController.Object.SendEmail(subscriptionViewModel);

        Assert.AreEqual(((ViewResult)result).ViewName, "Index");

    }
}

I have a controller called SubscriptionController. In there, I have a Action Method called SendEmail. I want to be able to run my Subscription/SendEmail using this Test method above. My view is a form with the following fields: First Name, Last Name, Email, Comments and a checkbox. I need to mock this form and also mock my controller, http request and context. I am a bit confused what to mock and what to use as real. Thanks for any clarification.

like image 851
Emerson de Mello Avatar asked Dec 14 '11 14:12

Emerson de Mello


1 Answers

Answer: you can mock the form post by setting up the form values in the Request.Form directly. Before I was mocking the HttpRequest, setting up the form values and then linking the httpRequest object to the HttpContext object. This approach didn't work.

I am posting the solution below, just compare I have done before and you will understand.

[TestMethod]
public void TestSendSubscriptionEmail()
{   
    //HTTP CONTEXT SET UP
    var httpContext = new Mock<HttpContextBase>();           

    var routeData = new RouteData();
    httpContext.Setup(c => c.Request.RequestContext.RouteData).Returns(routeData);

    httpContext.Setup(c => c.Request.Form).Returns(delegate()
    {
        var nv = new NameValueCollection();
        nv.Add("FirstName", "John");
        nv.Add("LastName", "Smith");
        nv.Add("Email", "[email protected]");
        nv.Add("Comments", "Comments are here...");
        nv.Add("ReceiveUpdates", "true");
        return nv;
    });

    httpContext.Setup(c => c.Request.Path).Returns("/Subscription/SendEmail");

    var subscriptionViewModel = new Mock<ISubscriptionViewModel>();

    subscriptionViewModel.Setup(h => h.HttpContext).Returns(httpContext.Object);

    subscriptionViewModel.Setup(h => h.FirstName).Returns(httpContext.Object.Request.Form["FirstName"]);
    subscriptionViewModel.Setup(h => h.LastName).Returns(httpContext.Object.Request.Form["LastName"]);
    subscriptionViewModel.Setup(h => h.Email).Returns(httpContext.Object.Request.Form["Email"]);
    subscriptionViewModel.Setup(h => h.Comments).Returns(httpContext.Object.Request.Form["Comments"]);
    subscriptionViewModel.Setup(h => h.InvestmentUpdates).Returns(bool.Parse(httpContext.Object.Request.Form["ReceiveUpdates"]));

    var subscriptionController = new SubscriptionController(subscriptionViewModel.Object);

    var result = subscriptionController.SendEmail(subscriptionViewModel.Object);

    Assert.AreEqual(((ViewResult)result).ViewName, "Index");

}
like image 175
Emerson de Mello Avatar answered Nov 22 '22 17:11

Emerson de Mello