如何 Mock System.Web.Hosting.HostingEnvironment.MapPath 虛擬路徑

同事想要為負責的專案加上測試保護,讓之後的修改可以降低風險,但很快地就遇上問題:專案在開發階段時並沒有加上任何測試,專案的部份語法是相對較難測試的,同事遇到的問題就是其一:特定方法使用了 System.Web.Hosting.HostingEnvironment.MapPath 去讀取檔案內容。

使用 fakes

  1. 加入 Fakes assembly

    • 開啟測試專案的 References 資料夾
    • System.Web.Http 上按右鍵 –> Add Fakes Assembly

      1addfake

  2. 專案加入 dll 與 config

程式碼 mock

  1. create ShimsContext

    • namespace Microsoft.QualityTools.Testing.Fakes

      using Microsoft.QualityTools.Testing.Fakes;
      
    • ShimsContext Create

      using (ShimsContext.Create())
      {
      }
      
  2. 指定 HostingEnvironment.MapPath

    ShimHostingEnvironment.MapPathString = (s => @"D:\yowkoTest\App_Data");
    
  3. 完整程式碼

    • api

      public class HomeController : Controller
      {
          [HttpGet]
          public string MapPath()
          {
              return HostingEnvironment.MapPath("~/App_Data");
          }
      }
      
    • test

      using (ShimsContext.Create())
      {
          string path = @"D:\yowkoTest\App_Data";
          ShimHostingEnvironment.MapPathString = (s => path);
          HomeController controller = new HomeController();
          var actual= controller.MapPath();
          Assert.AreEqual(path,actual);
      }
      

參考資料

  1. Fake Assembly 無法自動產生 *.Fakes dll 及出現 build fail