当前位置:  开发笔记 > 编程语言 > 正文

模拟Asp.net-mvc控制器上下文

如何解决《模拟Asp.net-mvc控制器上下文》经验,为你挑选了5个好方法。

因此控制器上下文取决于一些asp.net内部.有什么方法可以干净地模拟这些单元测试?当我只需要例如Request.HttpMethod来返回"GET"时,似乎很容易堵塞大量设置的测试.

我在网上看过一些例子/助手,但有些已经过时了.认为这将是保持最新和最伟大的好地方.

我正在使用最新版本的犀牛嘲笑



1> Haacked..:

使用MoQ看起来像这样:

var request = new Mock();
request.Expect(r => r.HttpMethod).Returns("GET");
var mockHttpContext = new Mock();
mockHttpContext.Expect(c => c.Request).Returns(request.Object);
var controllerContext = new ControllerContext(mockHttpContext.Object
, new RouteData(), new Mock().Object);

我认为Rhino Mocks语法类似.


这在MVC3中不再有效.当在RouteData上调用非虚拟的,不可模拟的方法GetRequiredString时,传入一个空的RouteData将抛出异常.
@ScottKoon请提供它应该是什么样子的演示

2> Maksym Kozle..:

这是一个使用MsTest和Moq的示例单元测试类,它可以模拟HttpRequest和HttpResponse对象.(.NET 4.0,ASP.NET MVC 3.0)

控制器操作从请求获取值并在响应对象中设置http标头.可以以类似的方式模拟其他http上下文对象

[TestClass]
public class MyControllerTest
{
    protected Mock HttpContextBaseMock;
    protected Mock HttpRequestMock;
    protected Mock HttpResponseMock;

    [TestInitialize]
    public void TestInitialize()
    {
        HttpContextBaseMock = new Mock();
        HttpRequestMock = new Mock();
        HttpResponseMock = new Mock();
        HttpContextBaseMock.SetupGet(x => x.Request).Returns(HttpRequestMock.Object);
        HttpContextBaseMock.SetupGet(x => x.Response).Returns(HttpResponseMock.Object);
    }

    protected MyController SetupController()
    {
        var routes = new RouteCollection();
        var controller = new MyController();
        controller.ControllerContext = new ControllerContext(HttpContextBaseMock.Object, new RouteData(), controller);
        controller.Url = new UrlHelper(new RequestContext(HttpContextBaseMock.Object, new RouteData()), routes);
        return controller;
    }

    [TestMethod]
    public void IndexTest()
    {
        HttpRequestMock.Setup(x => x["x"]).Returns("1");
        HttpResponseMock.Setup(x => x.AddHeader("name", "value"));

        var controller = SetupController();
        var result = controller.Index();
        Assert.AreEqual("1", result.Content);

        HttpRequestMock.VerifyAll();
        HttpResponseMock.VerifyAll();
    }
}

public class MyController : Controller
{
    public ContentResult Index()
    {
        var x = Request["x"];
        Response.AddHeader("name", "value");
        return Content(x);
    }
}



3> Dane O'Conno..:

这是Jason链接的片段.它与菲尔的方法相同,但使用犀牛.

注意:mockHttpContext.Request被存根以 mockRequest的内部被删除之前返回mockRequest .我相信这个订单是必需的.

// create a fake web context
var mockHttpContext = MockRepository.GenerateMock();
var mockRequest = MockRepository.GenerateMock();
mockHttpContext.Stub(x => x.Request).Return(mockRequest);

// tell the mock to return "GET" when HttpMethod is called
mockRequest.Stub(x => x.HttpMethod).Return("GET");            

var controller = new AccountController();

// assign the fake context
var context = new ControllerContext(mockHttpContext, 
                  new RouteData(), 
                  controller);
controller.ControllerContext = context;

// act
...



4> Gabe Moothar..:

这个程序似乎在MVC2中略有改变(我正在使用RC1).如果动作需要特定的方法([HttpPost],[HttpGet]),Phil Haack的解决方案对我不起作用.在Reflector中浏览,看起来验证这些属性的方法已经改变.MVC现在检查request.Headers,request.Formrequest.QueryString一个X-HTTP-Method-Override值.

如果为这些属性添加模拟,它可以工作:

var request = new Mock();
request.Setup(r => r.HttpMethod).Returns("POST");
request.Setup(r => r.Headers).Returns(new NameValueCollection());
request.Setup(r => r.Form).Returns(new NameValueCollection());
request.Setup(r => r.QueryString).Returns(new NameValueCollection());

var mockHttpContext = new Mock();
mockHttpContext.Expect(c => c.Request).Returns(request.Object);
var controllerContext = new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock().Object);



5> RoyOsherove..:

或者您可以使用Typemock Isolator执行此操作,而无需发送任何假控制器:

Isolate.WhenCalled(()=>HttpContext.Request.HttpMethod).WillReturn("Get");

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有