简单问题:在 asp.net mvc 中为 ajax 请求设置模拟

发布于 2024-10-30 01:15:58 字数 591 浏览 0 评论 0 原文

我是单元测试和 MVC 开发的新手。
我有一个关于在 asp.net mvc 中使用最小起订量进行单元测试的问题。我有一个接受 ajax 操作的控制器:

 [HttpPost,Authorize]
        public ActionResult GrabLink()
        {
            string username = HttpContext.User.Identity.Name;
            string rssUrl = Request.Params["Grablink"].ToString();
...}

此操作处理我从视图生成的 http 请求:

     var mockRequest = new Moq.Mock<HttpRequestBase>();

但我找不到定义在类中使用的参数的方法。另外,如果我想做 ajax post,有没有办法直接使用值绑定提供程序将值传递给控制器​​?

我是处理网络请求的新手。如果您有一些好的教程可以帮助您更好地理解 Http 请求(以及 Httpcontext 和 asp.net 中的相关类),请在此处发布。非常感谢!

I am new in unit test and MVC development.
I have a question for using moq for unit testing in asp.net mvc. I have a controller which accepts an ajax action:

 [HttpPost,Authorize]
        public ActionResult GrabLink()
        {
            string username = HttpContext.User.Identity.Name;
            string rssUrl = Request.Params["Grablink"].ToString();
...}

This action deals with the http request which I generate from the view:

     var mockRequest = new Moq.Mock<HttpRequestBase>();

but I can not find a way to define the parameters I used in the class. Also, is there any way to use the value binding provider directly to pass the value to the controller if I would like to do an ajax post?

I am a newbie in handling web request. If you have some good tutorial for better understanding the Http request (as well as the Httpcontext and related classes in asp.net) please post here. Thank you very much!

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

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

发布评论

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

评论(3

不一样的天空 2024-11-06 01:15:58

这对我来说非常有效:

var controller = new HomeController();

var context = new Mock<HttpContextBase>(MockBehavior.Strict);
var controllerContext = new Mock<ControllerContext>();

controllerContext.SetupGet(x => x.HttpContext.User.Identity.Name)
    .Returns("TestUser");
controllerContext.SetupGet(x => x.HttpContext.User.Identity.IsAuthenticated)
    .Returns(true);
controllerContext.SetupGet(x => x.HttpContext.Request.IsAuthenticated)
    .Returns(true);
controller.ControllerContext = controllerContext.Object;

// As a bonus, instantiate the Url helper to allow creating links
controller.Url = new UrlHelper(
    new RequestContext(context.Object, new RouteData()), new RouteCollection());

这将允许您将任何您想要的用户初始化为经过身份验证的用户,最后一行将允许您在控制器中使用 Url 帮助程序,即使您正在调用来自单元测试。

This works very well for me:

var controller = new HomeController();

var context = new Mock<HttpContextBase>(MockBehavior.Strict);
var controllerContext = new Mock<ControllerContext>();

controllerContext.SetupGet(x => x.HttpContext.User.Identity.Name)
    .Returns("TestUser");
controllerContext.SetupGet(x => x.HttpContext.User.Identity.IsAuthenticated)
    .Returns(true);
controllerContext.SetupGet(x => x.HttpContext.Request.IsAuthenticated)
    .Returns(true);
controller.ControllerContext = controllerContext.Object;

// As a bonus, instantiate the Url helper to allow creating links
controller.Url = new UrlHelper(
    new RequestContext(context.Object, new RouteData()), new RouteCollection());

This will allow you to initialize any user you want as an authenticated user, and the last line will allow you to user the Url helper within the controller even though you're calling it from a unit test.

花开柳相依 2024-11-06 01:15:58

正如 Scott 所说,HttpContext 使控制器难以测试。无论如何,他在此处找到了一个很好的解决方案。

顺便说一句,如果通过 POST 或 GET 分配,为什么不将 rssUrl 设为参数?

例如

//POST: /GrabLink?rssUrl=bla bla...

[HttpPost,Authorize]
public ActionResult GrabLink(IPrincipal user, string rssUrl) {
    string userName = user.Name;
}

As Scott said HttpContext makes Controllers hard to test. Anyway he's got a pretty solution at here.

BTW why didn't you make rssUrl a parameter if it is assigning by POST or GET?

e.g.

//POST: /GrabLink?rssUrl=bla bla...

[HttpPost,Authorize]
public ActionResult GrabLink(IPrincipal user, string rssUrl) {
    string userName = user.Name;
}
放我走吧 2024-11-06 01:15:58

好的,@cem 很好地回答了你的第二个问题。

对于您的第一个,nerddinner,如果我没记错的话,当您使用单元测试创​​建一个新的互联网应用程序时,在 Visual Studio 中,为 HttpContext 提供以下模拟类。它位于此文件的底部。

您可以使用这些(或使用 VS 创建一个新的 Internet 应用程序 + 测试)并为您的测试复制所有假类。 (我在下面写了一个 Moq 示例)

它看起来像这样:

public class MockHttpContext : HttpContextBase {
    private IPrincipal _user;

    public override IPrincipal User {
        get {
            if (_user == null) {
                _user = new MockPrincipal();
            }
            return _user;
        }
        set {
            _user = value;
        }
    }

    public override HttpResponseBase Response
    {
        get
        {
            return new MockHttpResponse();
        }
    }
}

public class MockHttpResponse : HttpResponseBase {
    public override HttpCookieCollection Cookies
    {
        get
        {
            return new HttpCookieCollection();
        }
    }
}

未测试,但要使用模拟,它看起来像这样:

var fakeReqBase = new Mock<HttpRequestBase>();
fakeReqBase.Setup(f => f.User).Returns(new GenericIdentity("FakeUser"));
//generic identity implements IIdentity
fakeUserRepo.Object;//this returns fake object of type HttpRequestBase

签出 起订量快速入门。它很容易习惯,而且流畅的界面确实很有帮助。

Ok, @cem covered your second question very well.

For your first, nerddinner, and If I'm not mistaken, when you create a new Internet Application with Unit test, in Visual Studio, have the following mock classes for HttpContext. Its at the bottom of this file.

You could use these (or create a new Internet App +Tests with VS) and copy all the fake classes for your tests. (I wrote a Moq example below)

It looks like this:

public class MockHttpContext : HttpContextBase {
    private IPrincipal _user;

    public override IPrincipal User {
        get {
            if (_user == null) {
                _user = new MockPrincipal();
            }
            return _user;
        }
        set {
            _user = value;
        }
    }

    public override HttpResponseBase Response
    {
        get
        {
            return new MockHttpResponse();
        }
    }
}

public class MockHttpResponse : HttpResponseBase {
    public override HttpCookieCollection Cookies
    {
        get
        {
            return new HttpCookieCollection();
        }
    }
}

Not tested, but to Use mock it would look like this:

var fakeReqBase = new Mock<HttpRequestBase>();
fakeReqBase.Setup(f => f.User).Returns(new GenericIdentity("FakeUser"));
//generic identity implements IIdentity
fakeUserRepo.Object;//this returns fake object of type HttpRequestBase

Checkout the Moq Quickstart. Its quite easy to get used to, and the fluent interface really helps.

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