0

I am trying to understand why HttpContext.AuthenticateAsync() method fails when I set the httpContext using the following code

public static void SetMockAuthenticatedControllerContext(this Controller controller,string userName)
        {
            var httpContext = MockHttpContext(userName);
            var controllerContext = new ControllerContext
            {
                HttpContext= httpContext,
                RouteData=new Microsoft.AspNetCore.Routing.RouteData()
            };
            controller.ControllerContext = controllerContext;
        }
public static HttpContext MockHttpContext(string userName)
        {
            var context = new Mock<HttpContext>();
            var request = new Mock<HttpRequest>();
            var response = new Mock<HttpResponse>();
            var session = new Mock<ISession>();
            var user = new Mock<ClaimsPrincipal>();
            var identity = new Mock<ClaimsIdentity>();
            var features = new Mock<IFeatureCollection>();
            var authService = new Mock<IAuthenticationService>();
            var prodvierServiceMock = new Mock<IServiceProvider>();
            var authTicket = new AuthenticationTicket(new ClaimsPrincipal(), "External");

            authService.Setup(c => c.AuthenticateAsync(It.IsAny<HttpContext>(), It.IsAny<string>()))
                .Returns(Task.FromResult(AuthenticateResult.Success(authTicket)));
            prodvierServiceMock.Setup(c => c.GetService(typeof(IAuthenticationService))).Returns(authService);
            context.Setup(ctx => ctx.Request).Returns(request.Object);
            context.Setup(ctx => ctx.Response).Returns(response.Object);
            context.Setup(ctx => ctx.Session).Returns(session.Object);
            //context.Setup(ctx=>ctx.GetServerVariable(It.IsAny<string>())).Returns()
            context.Setup(ctx => ctx.User).Returns(user.Object);
            context.Setup(x => x.RequestServices).Returns(prodvierServiceMock.Object);
            context.Setup(ctx => ctx.Features).Returns(features.Object);
            context.Setup(ctx => ctx.User.Identity).Returns(identity.Object);
            identity.Setup(x => x.IsAuthenticated).Returns(true);
            identity.Setup(x => x.Name).Returns(userName);
            return context.Object;
        }

and I am calling this in my controller test class as follows:

HttpContextFactory.SetMockAuthenticatedControllerContext(mycontrollerInstance,userName);

then call

var result = controller.Index();

which throws the following error:

Unable to cast object of type 'Moq.Mock`1[Microsoft.AspNetCore.Authentication.IAuthenticationService]' to type 'Microsoft.AspNetCore.Authentication.IAuthenticationService

Please help me understand what i am doing wrong. Thanks for the help.

  • 1
    `prodvierServiceMock.Setup(c => c.GetService(typeof(IAuthenticationService))).Returns(authService);` should return `....Returns(authService.Object)` instead – Nkosi Aug 03 '21 at 14:42
  • Consider reviewing my answer here as well https://stackoverflow.com/a/47199298/5233410 – Nkosi Aug 03 '21 at 14:46
  • You are mocking too many things. Use `DefaultHttpContext` with a few of the necessary mocks. It will greatly simplify your setup – Nkosi Aug 03 '21 at 14:47
  • Thanks NKosi. this Made my day and I didn't see this error till now. Thanks – Rajesh Kasani Aug 03 '21 at 14:48

0 Answers0