2011-04-03 96 views
2

我是单元测试和MVC开发新手。
我有一个在asp.net mvc中使用moq进行单元测试的问题。我有它接受一个Ajax动作的控制器:与HTTP请求这是我从视图生成简单的问题:在asp.net中设置模拟ajax请求mvc

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

此操作涉及:

但我不能找到一种方法来定义参数予在课堂上使用。另外,有没有办法直接使用值绑定提供程序将值传递给控制器​​,如果我想做一个Ajax的帖子?

我是处理web请求的新手。如果你有一些很好的教程来更好地理解Http请求(以及HttpContext和asp.net中的相关类),请在这里发帖。非常感谢你!

回答

1

由于Scott表示HttpContext使控制器很难测试。无论如何,他在here有一个漂亮的解决方案。

顺便说一句,如果通过POST或GET指定参数,为什么不给rssUrl一个参数?

例如

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

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

非常感谢。你的解决方案看起来非常整齐。我会在稍后尝试。 – Seen 2011-04-04 03:42:16

+0

不客气。请让我知道如果它不起作用。 – cem 2011-04-04 04:46:24

1

好的,@cem很好地涵盖了你的第二个问题。

为了您的第一,nerddinner,并且如果我没有记错的话,当你创建单元测试一个新的互联网应用,在Visual Studio中,有HttpContext以下mock类。它在this file的底部。

你可以使用这些(或创建一个新的互联网应用程序+ VS测试),并复制所有假类为您的测试。 (我写了下面一个起订量例子)

它看起来像这样:

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 

结帐的Moq Quickstart 。它很容易习惯,流畅的界面真的有帮助。

+0

感谢您的参考。我会在稍后处理它。 – Seen 2011-04-04 17:12:41

2

这工作对我非常好:

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帮手,即使你从单元测试中调用它。

+0

这种方法看起来非常整齐...我学到了很多东西。谢谢! – Seen 2011-04-04 15:28:19

+0

@Seen - 不客气,乐于帮助 :) – 2011-04-04 15:37:44