Question

How can I use Microsoft Fakes to mock User.Identity.Name when unit testing MVC 4 application with Visual Studio 2012. I'm writing unit test for item create action method.

[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);
        }
    }

These are the action method and test method I have written. If there is better way to do this other than MS Fakes please tell me, (not another mocking framework).

Was it helpful?

Solution

Assuming you've added Fakes references for System.Web and System, you can do something like this inside your using (ShimsContext.Create()) block:

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; };

OTHER TIPS

User is actually HttpContext.User. So you could use System.Fakes.ShimHttpContext to return a custom implementation of the whole IPrincipal containing the right Identity.Name...

I ended up with a similar answer to @Sven, but ended up stubbing the context instead of using a shim.

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top