1

如何在使用Visual Studio 2012單元測試MVC 4應用程序時使用Microsoft Fakes來模擬User.Identity.Name。 我正在爲項目創建操作編寫單元測試方法。如何使用Microsoft Fakes來模擬User.Identity.Name

[HttpPost] 

    public ActionResult Create([Bind(Include = "Name")]Category category) 
    { 

     if (categoryService.IsNameExists(category.Name)) 
     { 
      ModelState.AddModelError("Name", "Category name already exists!"); 
      return View(category); 
     } 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       UserProfile p = new UserProfile(); 
       p.UserName = User.Identity.Name; 

       category.CreatedBy = p; 
       category.CreatedDate = DateTime.Now; 
       category.Active = true; 
       category.DeletedBy = null; 

       category = categoryService.SaveCategory(category); 
       return RedirectToAction("Index"); 
      } 
      return View(category); 
     } 
     catch (DataException dex) 
     { 

     } 
    } 


[TestMethod] 
    public void Create() 
    { 
     Category createdCategory = new Category(); 
     ICategoryService service = new StubICategoryService() 
     { 
      SaveCategoryCategory = (category) => { return category; } 
     }; 
     CategoryController controller = new CategoryController(service); 

     using (ShimsContext.Create()) 
     { 
      System.Fakes.ShimDateTime.NowGet =() => 
      { return new DateTime(2000, 1, 1); }; 

      ViewResult result = controller.Create(createdCategory) as ViewResult; 

      Assert.IsNotNull(result); 
     } 
    } 

這些是我寫的操作方法和測試方法。如果還有更好的方法可以做到這一點,請告訴我,(不是另一個嘲諷框架)。

+0

不是直接調用「User.Indenty.Name」,而是使用方法GetCurrentUser創建一個單獨的類「CustomUserContext」。這樣你可以在測試方法中用你喜歡的任何東西來模擬CustomUserContext。 – artokai

回答

1

System.WebSystem假設你已經添加了假貨的引用,你可以做這樣的事情你using (ShimsContext.Create())塊中:

var context = new System.Web.Fakes.ShimHttpContext(); 
var user = new StubIPrincipal 
{ 
    IdentityGet =() => 
    { 
     var identity = new StubIIdentity {NameGet =() => "foo"}; 
     return identity; 
    } 
}; 

context.UserGet =() => principal; 
System.Web.Fakes.ShimHttpContext.CurrentGet =() => { return context; }; 
+0

可能最好在shim方法之外聲明存根實例,所以它不會在每次獲取時重新創建。這在一些罕見的情況下可能很重要。 – Magus

+0

這仍然會將用戶名作爲空值。這是價值觀,而debugging-的IPrincipal 的System.Web.HttpContext.Current.User 存根[System.Security.Principal.Fakes.StubIPrincipal]:存根的IPrincipal 身份:IIdentity的 的存根this.HttpContext.User '((System.Web.Mvc.Controller)(this))。HttpContext'爲空 – Nashpaw

+0

@Nashpaw更新您的問題與您更新的代碼 –

0

User實際上是HttpContext.User。因此,您可以使用System.Fakes.ShimHttpContext返回包含正確Identity.Name的整個IPrincipal的自定義實現...

+0

@ledbutter有相同的想法,但更好的演示文稿,讚揚你! – eFloh

0

我最終得到了類似於@Sven的答案,但結束了對上下文的扼殺,而不是使用墊片。

using (AccountController controller = new AccountController()) 
{ 
    StubHttpContextBase stubHttpContext = new StubHttpContextBase(); 

    controller.ControllerContext = new ControllerContext(stubHttpContext, new RouteData(), controller); 

    StubIPrincipal principal = new StubIPrincipal(); 
    principal.IdentityGet =() => 
    { 
     return new StubIIdentity 
     { 
      NameGet =() => "bob" 
     }; 
    }; 
    stubHttpContext.UserGet =() => principal; 
} 
相關問題