dyarosh
asked on
HttpResponseBase.Cache invocation failed with mock behavior strict error
I am trying to do TDD under ASP.NET C# MVC 4. I am trying to test a custom attribute and when the test is successful and returns true I get the above error. I tried changing my MockBehavior to Loose but it still throws an exception.
What is the best way to Mock the HttpResponseBase? Here is what I have so far:
AuthUser AuthorizeAttribute:
The failure part works because it redirects to another Controller/Action on failure.
Here is my test:
I tried to mock the Cache but I am getting an error trying to set it up.
Any help would be greatly appreciated!
MockExceptionError.fw.png
MockCacheError.fw.png
What is the best way to Mock the HttpResponseBase? Here is what I have so far:
AuthUser AuthorizeAttribute:
public class AuthUser : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// If Session isn't defined, user cannot be authorized
if (httpContext.Session == null)
return false;
// If User isn't authenticated return false
if (!httpContext.User.Identity.IsAuthenticated)
return false;
// Check which Roles if any need to be checked
if (Roles.Contains("IST")) // Intranet Support Team - GroupID = 261
{
// If user is not part of the Intranet Support Team Group, user is not authorized
if (httpContext.Session["GroupID"] == null || httpContext.Session["GroupID"].ToString() != "261")
return false;
}
return true;
}
private class RedirectController : Controller
{
public ActionResult RedirectToSomewhere()
{
return RedirectToAction("Authorize", "Error");
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = (new RedirectController()).RedirectToSomewhere();
}
}
The failure part works because it redirects to another Controller/Action on failure.
Here is my test:
[TestClass]
public class AuthorizeTest
{
private AuthorizeAttribute attribute;
private AuthorizationContext authorizationContext;
internal class FakeController : Controller
{
public ActionResult Nothing()
{
return new EmptyResult();
}
}
private void SetupSession(string sessionStr = "GroupID", string value = "261")
{
var mockContext = Mock.Get(authorizationContext.HttpContext);
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupGet(x => x[sessionStr]).Returns(value);
// Return the mock.
mockContext.SetupGet(x => x.Session).Returns(mockSession.Object);
}
private void Authorize()
{
attribute.OnAuthorization(authorizationContext);
}
[TestInitialize]
public void TestSetup()
{
attribute = new AuthUser();
attribute.Roles = "IST";
// Get FakeController for test
var controller = new FakeController();
// Setup Server Mock
var server = new Mock<HttpServerUtilityBase>();
// Setup Response Mock
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(r => r.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
//esponse.SetupGet(r => r.Cache).Returns(HttpRuntime.Cache);
// Setup Request Mock
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(r => r.UserHostAddress).Returns("127.0.0.1");
request.SetupGet(r => r.ApplicationPath).Returns("/");
request.SetupGet(r => r.Url).Returns(new Uri("http://localhost/", UriKind.Absolute));
// Setup Session Mock
var session = new Mock<HttpSessionStateBase>();
session.Setup(s => s.SessionID).Returns(Guid.NewGuid().ToString());
// Setup Identity
var identity = new GenericIdentity("DefaultUser");
var principal = new GenericPrincipal(identity, null);
// Mock the HttpContext
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);
context.SetupGet(c => c.Cache).Returns(HttpRuntime.Cache);
context.SetupGet(c => c.User).Returns(principal);
context.SetupGet(c => c.User.Identity.IsAuthenticated).Returns(true);
// Mock the controller context (using the objects mocked above)
ControllerContext ctx = new ControllerContext();
ctx.HttpContext = context.Object;
// Setup the authorizationContext
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 SuccessWhenGroupIDIsIST()
{
// Arrange
SetupSession("GroupID", "261");
// Act
Authorize();
// Assert
// ToDo: THE TEST WORKS AS DESIGNED BUT CAN'T FIGURE OUT HOW TO CHECK THE RESULT SO THE TEST WILL PASS - CURRENTLY THE TEST FAILS
Assert.AreSame(typeof(System.Web.Mvc.RedirectToRouteResult), authorizationContext.Result);
}
I tried to mock the Cache but I am getting an error trying to set it up.
Any help would be greatly appreciated!
MockExceptionError.fw.png
MockCacheError.fw.png
ASKER
I am trying to mock the cache because the error I get when I return true from IsValid is a null reference in Response.cache.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It only took me 28 days but I finally found the solution on my own.
The reason you get the error is because you are mixing types. r.Cache is of type HttpCachePolicyBase and HttpRuntime.Cache is of type Cache.
Be careful with having global mock objects as you should really write your tests so that no two tests interfere with each other. Doing so helps keep the things that you are testing isolated from each other by way of avoiding side effects. Myself, I create mocks within each test method, unless I can guarantee that no two tests will interfere with the others. By having distinct mocks in each test method, you ensure that no two tests will affect one another.