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; 
} 
相关问题