I am using Visual Studio 2015 Enterprise Update 1 and ASP.NET 5 rc1-final to build an endpoint that both issues and consumes JWT tokens as described in detail here.
Now I'm moving on to unit testing and encountering friction when testing certain aspects of AspNet.Security.OpenIdConnect.Server (OIDC/ASOS). Specifically, some ASOS primitives such as LogoutEndpointContext aren't abstract so they aren't easily mocked. Normally I'd just throw a fake at these kinds of types but DNX doesn't appear to support fakes, at least not yet. These types are also sealed so I can't specialize them.
This has forced me to write some brittle reflection code in order to construct these kinds of sealed ASOS types. Here's an example XUnit tests that needs a LogoutEndpointContext so I can test my OpenIdConnectServerProvider event handling (in this case a non-POST logout should throw an exception); note the reflection I'm having to do in order to instantiate a LogoutEndpointContext:
[Fact]
async public Task API_Initialization_Services_AuthenticatedUser_Authentication_LogoutEndpoint_XSRF_Unit()
{
// Arrange
Mock<HttpRequest> mockRequest = new Mock<HttpRequest>();
mockRequest.SetupGet(a => a.Method).Returns(() => "Not Post");
Mock<HttpContext> mockContext = new Mock<HttpContext>();
mockContext.SetupGet(a => a.Request).Returns(() => mockRequest.Object);
OpenIdConnectServerOptions options = new OpenIdConnectServerOptions();
OpenIdConnectMessage request = new OpenIdConnectMessage();
// I would prefer not to use reflection
var ctorInfo = typeof(LogoutEndpointContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single();
LogoutEndpointContext context = (LogoutEndpointContext)ctorInfo.Invoke(new object[] {mockContext.Object,options, request});
// Act
AuthenticationEvents authenticationEvents = new AuthenticationEvents();
// Assert
await Assert.ThrowsAsync<SecurityTokenValidationException>(() => authenticationEvents.LogoutEndpoint(context));
}
Any advice on how to better instantiate/mock/fake/specialize sealed ASOS types like LogoutEndpointContext would be very much appreciated.