MVC 3单元测试 - 获取实际响应数据

时间:2011-05-12 18:30:48

标签: unit-testing asp.net-mvc-3 moq

所有

我正在使用ASP.NET MVC 3开发和单元测试交互式语音应用程序,其控制器返回包含VoiceXML的视图。我想创建捕获实际VoiceXML输出的单元测试,以便我可以对其进行模式验证。

我的阅读和测试让我看到了使用Moq的Scott H的FakeHttpContext,以及这里的几个回复。一切都正确编译,我正在尝试做以下事情:

[TestMethod]
public void WelcomeTest1()
{
     EmergencyController controller = new EmergencyController();
     controller.ControllerContext = new  ControllerContext(MvcMockHelpers.FakeHttpContext("~/Emergency/Welcome"), new RouteData(), controller);

     ViewResult result = (controller.Welcome()) as ViewResult;
 .
 .
     Assert.IsTrue(controller.ControllerContext.HttpContext.Response.OutputStream.Length > 0);
     // assert schema validation on the output here
}

然而,单步执行此操作,我可以看到正在调用欢迎视图,但我正在寻找Response.Output中的内容而没有找到任何内容。模拟设置如下,希望将CallBase设置为true实际上会写出一些东西。我发现了一些我添加到FakeHttpContext构造函数中的代码,它可能会调用StringWriter,但无济于事:

public static HttpContextBase FakeHttpContext()
{
    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>() { CallBase = true };
    var response = new Mock<HttpResponseBase>();
    var session = new Mock<HttpSessionStateBase>();
    var server = new Mock<HttpServerUtilityBase>();

    context.Setup(ctx => ctx.Request).Returns(request.Object);
    context.Setup(ctx => ctx.Response).Returns(response.Object);
    context.Setup(ctx => ctx.Session).Returns(session.Object);
    context.Setup(ctx => ctx.Server).Returns(server.Object);
    response.Setup(r => r.OutputStream).Returns(new MemoryStream());
    response.Setup(r => r.Headers).Returns(new NameValueCollection());           

    var writer = new StringWriter();
    var wr = new SimpleWorkerRequest("", "", "", "", writer);        
    HttpContext.Current = new HttpContext(wr);

    return context.Object;
}

我确定我错过了一些明显的东西,但我现在很难过。

由于

Jim Stanley

Blackboard Connect

1 个答案:

答案 0 :(得分:0)

结果不会在ViewResult中填充。换句话说,您在控制器中调用return View()不会呈现视图,而是mvc获取viewresult并在稍后的request-sycle中呈现它。您需要做的是为ViewResults创建一个渲染函数,如下所示:

using System;
using System.IO;
using System.Web.Mvc;

namespace CoPrice.Helpers
{
    public static class ViewRendrer
    {
        public static string ToHtml(this ViewResult result, Controller controller)
        {
            controller.ViewData.Model = result.Model;
            try
            {
                using (StringWriter sw = new StringWriter())
                {
                    ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, result.ViewName);
                    ViewContext context = new ViewContext(controller.ControllerContext, viewResult.View, result.ViewData, result.TempData, sw);
                    viewResult.View.Render(context, sw);

                    return sw.GetStringBuilder().ToString();
                }
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }
    }
}

然后你可以做result.ToHtml(控制器)获取实际数据(这只适用于RazorViews我认为,虽然我不确定,这是我至少使用它的。)