How do I unit test a controller action that uses ther Controller.User variable?

后端 未结 2 716
轮回少年
轮回少年 2021-02-20 09:43

I have a controller action that automatically redirects to a new page if the user is already logged in (User.Identity.IsAuthenticated). What is the best way to writ

2条回答
  •  独厮守ぢ
    2021-02-20 10:37

    That's not the simplest thing to do, but it can be done. The User property simply delegates to Controller.HttpContext.User. Both are non-virtual read-only properties, so you can't do anything about them. However, Controller.HttpContext delegates to ControllerBase.ControllerContext which is a writable property.

    Therefore, you can assign a Test Double HttpContextBase to Controller.ControllerContext before exercising your System Under Test (SUT). Using Moq, it would look something like this:

    var user = new GenericPrincipal(new GenericIdentity(string.Empty), null);
    var httpCtxStub = new Mock();
    httpCtxStub.SetupGet(ctx => ctx.User).Returns(user);
    
    var controllerCtx = new ControllerContext();
    controllerCtx.HttpContext = httpCtxStub.Object;
    
    sut.ControllerContext = controllerCtx;
    

    Then invoke your action and verify that the return result is a RedirectResult.

    This test utilizes the implicit knowledge that when you create a GenericIdentity with an empty name, it will return false for IsAuthenticated. You could consider making the test more explicit by using a Mock instead.

提交回复
热议问题