1

Server.MapPathリソースファイルをロードし、ファイルへのパスを取得するために使用するMVCコントローラーがあります。Microsoft Fakesフレームワークを使用してコントローラーオブジェクトのServerプロパティをモックアウトしたいと思います(他のフレームワークを使用してこれを行う方法を知っています)。

コードは次のとおりです。

    [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」メソッドです。

4

1 に答える 1

1

Visual Studio 2012 Update 1以降、スタブを使用してController.Serverプロパティを迂回できます。

テストプロジェクトに次の.Fakesファイルを使用します。

<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(@"\Content\Test.txt", result.FileName);
}

今後のUpdate2で​​は、Shimsを使用してController.Serverプロパティを直接迂回することもできます。これは、このアプローチで必要になる追加の.Fakesファイルです。

<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(@"\Content\Test.txt", result.FileName);
    }
}

部分的に信頼された呼び出し元を許可するSystem.Web.Mvcなどのアセンブリに関連するFakesランタイムの制限により、このアプローチは現在のバージョン(Update 1)では機能しないことに注意してください。今日2番目のテストを実行しようとすると、VerificationExceptionが発生します。

于 2012-12-01T00:42:30.467 に答える