I am trying to write unit tests for my controller class which retrieves a token with the following command:
string token = await HttpContext.GetTokenAsync("access_token");
Therefore I mocked the HttpContext with the following code:
public static HttpContext MakeFakeContext()
{
var serviceProvider = new Mock<IServiceProvider>();
var authservice = new Mock<IAuthenticationService>();
authservice.Setup(_ => _.GetTokenAsync(It.IsAny<HttpContext>(), It.IsAny<string>())).Returns(Task.FromResult("token"));
serviceProvider.Setup(_ => _.GetService(typeof(IAuthenticationService))).Returns(authservice);
return new DefaultHttpContext
{
RequestServices = serviceProvider.Object
};
}
I am setting the mocked context with:
var mockcontext = MakeFakeContext();
unitUnderTest.ControllerContext = new ControllerContext
{
HttpContext = mockcontext
};
Now when I run the unit test, I am getting the following error:
System.NotSupportedException : Unsupported expression: _ => _.GetTokenAsync(It.IsAny(), It.IsAny()) Extension methods (here: AuthenticationTokenExtensions.GetTokenAsync) may not be used in setup / verification expressions.
During my research I stumbled across solutions where you can mock specific parts that are involved under the hood which are not part of extensions. These are some of them: Moq IServiceProvider / IServiceScope, How to unit test HttpContext.SignInAsync()?. The second one shows a similar problem, which seems to work after I tried. But for some reason it does not work for the GetTokenAsync method.
Do you guys have any hint out there?
Unsupported expression: _ => _.GetTokenAsync(It.IsAny(), It.IsAny())
– SmetanaAuthenticateAsync
, which is what is ultimately called by the extension. – Smetana