How I solved:
protected static ActionExecutedContext FakeExecutedContext(IPrincipal principal = null,
Controller controller = null)
{
var request = new Mock<HttpRequestBase>();
request.SetupGet(x => x.HttpMethod).Returns("GET");
request.SetupGet(x => x.Url).Returns(new Uri("http://example.com/action"));
var httpContext = new Mock<HttpContextBase>();
httpContext.SetupGet(x => x.Request).Returns(request.Object);
// aqui adiciono o principal quando passado por parâmetro
if (principal != null)
httpContext.SetupGet(x => x.User).Returns(principal);
var executedContext = new Mock<ActionExecutedContext>();
executedContext.SetupGet(x => x.HttpContext).Returns(httpContext.Object);
if (controller != null)
executedContext.SetupGet(x => x.Controller).Returns(controller);
return executedContext.Object;
}
Simplifying the test method for this:
[TestMethod]
public void TentativaDeAcessoComPerfilInferiorAoSolicitadoPeloFiltro()
{
// variáveis
// Uma claim será setada com nível de acesso de Suporte
var identity = new ClaimsIdentity(new List<Claim>
{
new Claim(CustomClaimTypes.Perfil, Perfil.Suporte.ToString())
});
var principal = new GenericPrincipal(identity, new[] { "" });
// A simulação requer um nível de acesso Administrativo
var filter = new PerfilFilterAttribute(Perfil.Administrativo, Context);
var fakeExecutedContext = FakeExecutedContext(principal, new HomeController());
// execução
filter.OnActionExecuted(fakeExecutedContext);
// validação
// O resultado deve apontar um redirecionamento para o /Home/Index
Assert.IsNotNull(fakeExecutedContext.Controller.TempData["ErrorMessage"]);
Assert.IsNotNull(fakeExecutedContext.Result as RedirectResult);
Assert.AreEqual(((RedirectResult)fakeExecutedContext.Result).Url, "/Home/Index");
}
There is a detail in the filter that has been changed from:
var cookie = new CookieInfo(HttpContext.Current.User.Identity as ClaimsIdentity);
To:
var cookie = new CookieInfo(filterContext.HttpContext.User.Identity as ClaimsIdentity);