我有一个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)允许部分信任的调用方。如果您尝试今天运行第二个测试,您将获得验证异常。