How I resolved:
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’s a detail on the filter, which 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);
I know it’s just an example, but I could see the line
context.HttpContext = new HttpContext(httpRequest, httpResponse);
? The types are different. I believe I will need to pass values to the Main, as in the question how-to-a-controller-Asp-net-mvc-using-Moq-e-entity-framework. Can I somehow get through by going down this path? Thankful!– JamesTK
True, I switched the answer to
ControllerContext
.ControllerContext
has a property calledUser
, in which you can use to mockIPrincipal
.– Leonel Sanches da Silva
the
new HttpContext(httpRequest, httpResponse)
passed to thenew ControllerContext
are of different types.– JamesTK
I updated to Httpcontextbase.
– Leonel Sanches da Silva