如何使用 Moq 模拟 MVC 表单 POST

发布于 2024-12-21 05:03:37 字数 1668 浏览 1 评论 0原文

谁能告诉我如何使用 Moq 来模拟 MVC 表单帖子吗?

我想要的只是基于几个不同的表单帖子对我的方法进行单元测试。

我尝试用谷歌搜索这个问题,但没有从上到下的指南。

谢谢

编辑:添加代码

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

    }
}

我有一个名为 SubscriptionController 的控制器。 在那里,我有一个名为 SendEmail 的操作方法。 我希望能够使用上面的测试方法运行我的订阅/发送电子邮件。 我的视图是一个包含以下字段的表单:名字、姓氏、电子邮件、评论和复选框。 我需要模拟这个表单,还需要模拟我的控制器、http 请求和上下文。我有点困惑该模拟什么以及将什么用作真实的。感谢您的任何澄清。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

摘星┃星的人 2024-12-28 05:03:37

答:可以通过直接在Request.Form中设置表单值来模拟表单发布。在我模拟 HttpRequest 之前,设置表单值,然后将 httpRequest 对象链接到 HttpContext 对象。这个方法没有奏效。

我把解决方案贴在下面,对比一下我之前做过的,你就明白了。

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

}

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文