我正在使用 Visual Studio 2015 Enterprise Update 1 和 ASP.NET 5 rc1-final 来构建一个端点,该端点发出和使用 JWT 令牌,如这里详细描述的那样。
现在我开始进行单元测试,在测试 AspNet.Security.OpenIdConnect.Server (OIDC/ASOS) 的某些方面时遇到了摩擦。具体来说,一些 ASOS 原语,例如 LogoutEndpointContext 不是抽象的,因此它们不容易被模拟。通常我只会对这些类型进行假冒,但 DNX 似乎不支持假冒,至少现在还不支持。这些类型也是密封的,所以我不能专门化它们。
这迫使我编写一些脆弱的反射代码来构造这些密封的 ASOS 类型。这是一个需要 LogoutEndpointContext 的示例 XUnit 测试,因此我可以测试我的 OpenIdConnectServerProvider 事件处理(在这种情况下,非 POST 注销应该引发异常);注意我为了实例化 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));
}
任何关于如何更好地实例化/模拟/伪造/专门化像 LogoutEndpointContext 这样的密封 ASOS 类型的建议都将非常感激。