Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to Assert the Result property of AuthorizationContext in MVC unit testing

Posted on 2014-03-19
3
Medium Priority
?
1,120 Views
Last Modified: 2014-03-20
I am trying to do unit testing of an Authorize attribute.  I am using Moq to mock the HttpContext that is a required parameter of the AuthorizeCore method.  The only thing I have in the AuthorizeCore method is a check if the HttpContext.Session is null to return false.  This is working but because it is false, there is a RedirectController that redirects to a page that says the user is Unauthorized.

The problem I have is in my Unit Test I don't know how to test the authorizationContext.Result.

authorizationContext.Result displays the following when I print it in the Command Window:
[System.Web.Mvc.RedirectToRouteResult]: {System.Web.Mvc.RedirectToRouteResult}

If I hover over the authorizationContext.Result in Debug mode, I can drill down and get to Values that tell me the controller and action but I can't figure out how to access them.  (See attached Screen Shot).

So basically what I want is the correct syntax for doing an Assert that shows the test passed.

Here is the Authorize Attribute Code:
using System.Web;
using System.Web.Mvc;


namespace AppCatalog.Models
{

    public class AuthUser : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.Session == null)
                return false;

            bool authorized = false;
            return authorized;

        }


        private class RedirectController : Controller
        {
            public ActionResult RedirectToSomewhere()
            {
                return RedirectToAction("Authorize", "Error");
            }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
           
            filterContext.Result = (new RedirectController()).RedirectToSomewhere();
        }
    }
  
}

Open in new window


Here is my Test:
namespace AppCatalog.Tests
{
    [TestClass]
    public class AuthorizeTest
    {
        private AuthorizeAttribute attribute;
        private AuthorizationContext authorizationContext;

        internal class FakeController : Controller
        {
            public ActionResult Nothing()
            {
                return new EmptyResult();
            }
        }

        private void SetupSession(bool isAuthorized = true)
        {
            var mockContext = Mock.Get(authorizationContext.HttpContext);
            var mockSession = new Mock<HttpSessionStateBase>();
            mockSession.SetupGet(x => x["IsAuthenticated"]).Returns(isAuthorized);

            // Return the mock.
            mockContext.SetupGet(x => x.Session).Returns(mockSession.Object);
        }

        private void Authorize()
        {
            attribute.OnAuthorization(authorizationContext);
        }

        [TestInitialize]
        public void TestSetup()
        {
            attribute = new AuthUser();

            var controller = new FakeController();
            var server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
            var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
            var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
            request.Setup(r => r.UserHostAddress).Returns("127.0.0.1");
            var session = new Mock<HttpSessionStateBase>();
            session.Setup(s => s.SessionID).Returns(Guid.NewGuid().ToString());
            var context = new Mock<HttpContextBase>(MockBehavior.Strict);
            context.SetupGet(c => c.Items).Returns(new Mock<IDictionary>().Object);
            context.SetupGet(c => c.Request).Returns(request.Object);
            context.SetupGet(c => c.Response).Returns(response.Object);
            context.SetupGet(c => c.Server).Returns(server.Object);
            context.SetupGet(c => c.Session).Returns(session.Object);

            ControllerContext ctx = new ControllerContext();
            ctx.HttpContext = context.Object;

            authorizationContext = new AuthorizationContext();
            authorizationContext.Controller = controller;
            authorizationContext.HttpContext = ctx.HttpContext;

            var controllerDescriptor = new ReflectedControllerDescriptor(typeof(FakeController));
            var method = typeof(FakeController).GetMethod("Nothing");
            authorizationContext.ActionDescriptor = new ReflectedActionDescriptor(method, "Nothing", controllerDescriptor);
        }

        [TestMethod]
        public void FailsWhenSessionIsNull()
        {
            // Arrange
            Mock.Get(authorizationContext.HttpContext).SetupGet(x => x.Session).Returns((HttpSessionStateBase)null);

            // Act
            Authorize();

            // Assert
            Assert.AreEqual("Authorize", authorizationContext.Result.RouteValues.Values[0]);
            //Assert.AreSame(typeof(System.Web.Mvc.RedirectToRouteResult), authorizationContext.Result);
            //Assert.AreSame("<System.Web.Mvc.RedirectToRouteResult (System.Web.Mvc.RedirectToRouteResult)>", authorizationContext.Result);
        }
    }
}

Open in new window


The Assert lines that are commented out are my different attempts to get something working.  The current Assert line doesn't compile because of an error on RouteValues that is basically saying it doesn't exist.
AuthorizationContext.fw.png
0
Comment
Question by:dyarosh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 96

Accepted Solution

by:
Bob Learned earned 2000 total points
ID: 39942467
What are you looking to test with the AuthorizationContext.Result, which is an ActionResult?  The ActionResult is an abstract base class, so you would need to get the concrete result:

    ContentResult
    EmptyResult
    FileResult
    HttpStatusCodeResult
    JavaScriptResult
    JsonResult
    RedirectResult
    RedirectToRouteResult
    ViewResultBase
0
 

Author Comment

by:dyarosh
ID: 39943555
How do I go about getting the RedirectToRouteResult so I can check that it redirects to the correct page?
0
 

Author Closing Comment

by:dyarosh
ID: 39943606
I was able to cast the result to RedirectToRouteResult and pull the data I needed.  Thank you for your help.
0

Featured Post

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this Article, I will provide a few tips in problem and solution manner. Opening an ASPX page in Visual studio 2003 is very slow. To make it fast, please do follow below steps:   Open the Solution/Project. Right click the ASPX file to b…
User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

596 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question