模拟 ASP.NET MVC 控制器属性



我有一个MVC控制器,它加载资源文件并使用Server.MapPath来获取文件的路径。我想使用 Fakes 框架模拟控制器对象中的 Server 属性Microsoft(我知道如何使用其他框架执行此操作)。

代码如下:

    [HttpGet]
    public ActionResult GeneratePdf(string reportId)
    {
        var template = LoadTemplate(reportId);
        var document = pdfWriter.Write(GetReportModel(reportId), template);
        return File(document, MediaTypeNames.Application.Pdf);
    }
    private byte[] LoadTemplate(string reportId)
    {
        var templatePath = Server.MapPath(string.Format("~/ReportTemplates/{0}.docx", reportId));
        using(var templateContent = System.IO.File.OpenText(templatePath))
        {
            return Encoding.Default.GetBytes(templateContent.ReadToEnd());
        }
    }

我试图模拟的部分是"Server.MapPath"方法。

从 Visual Studio 2012 Update 1 开始,您可以使用存根绕道 Controller.Server 属性。

以下.测试项目中的假货文件:

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" Diagnostic="true">
  <Assembly Name="System.Web" Version="4.0.0.0"/>
  <StubGeneration>
    <Clear/>
    <Add FullName="System.Web.HttpContextBase!"/>
    <Add FullName="System.Web.HttpServerUtilityBase!"/>
  </StubGeneration>
  <ShimGeneration>
    <Clear/>
  </ShimGeneration>
</Fakes>

您可以像这样编写单元测试:

[TestMethod]
public void TestMethod1()
{
    var target = new TestController();
    var serverStub = new StubHttpServerUtilityBase();
    serverStub.MapPathString = (path) => path.Replace("~", string.Empty).Replace("/", @"");
    var contextStub = new StubHttpContextBase();
    contextStub.ServerGet = () => serverStub;
    target.ControllerContext = new ControllerContext();
    target.ControllerContext.HttpContext = contextStub;
    var result = (FilePathResult) target.Index();
    Assert.AreEqual(@"ContentTest.txt", result.FileName);
}

在即将推出的更新 2 中,您还可以直接使用填充码绕道 Controller.Server 属性。这是附加的.使用这种方法您将需要的假货文件。

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" Diagnostic="true">
  <Assembly Name="System.Web.Mvc" Version="4.0.0.0"/>
  <StubGeneration>
    <Clear/>
  </StubGeneration>
  <ShimGeneration>
    <Clear/>
    <Add FullName="System.Web.Mvc.Controller!"/>
  </ShimGeneration>
</Fakes>

这是测试:

[TestMethod]
public void TestMethod2()
{
    using (ShimsContext.Create())
    {
        var target = new TestController();
        var serverStub = new StubHttpServerUtilityBase();
        serverStub.MapPathString = (path) => path.Replace("~", string.Empty).Replace("/", @"");
        var controllerShim = new ShimController(target);
        controllerShim.ServerGet = () => serverStub;
        var result = (FilePathResult)target.Index();
        Assert.AreEqual(@"ContentTest.txt", result.FileName);
    }
}

请注意,此方法在当前版本(更新 1)中不起作用,因为与程序集相关的 Fakes 运行时(如 System.Web.Mvc)允许部分信任的调用方。如果您尝试今天运行第二个测试,您将获得验证异常。

最新更新