c# - 使用 Web API 对 JWT token 进行单元测试

标签 c# unit-testing asp.net-web-api2 jwt tdd

我正在尝试使用 Web API2、JWT、Microsoft.IdentityModel.JsonWebTokens 5.2.422 和本文中概述的 token 验证逻辑:http://www.decatechlabs.com/secure-webapi-using-jwt

当我重复文章中的步骤(包括通过 ReSTLet 测试 API)时,一切对我的项目都很有用。但是,我正在尝试为此项目使用测试驱动开发 (TDD),并且我希望测试所有内容在我的测试中是否正常工作,包括 token 验证处理程序。如果我在单元测试中直接调用它们,我可以测试我的 Controller ,但这绕过了实际的 token 验证处理程序。因此,我尝试使用自托管 HTTP 来正确执行完整的 API,包括所有 token 验证处理程序逻辑。这是我获取 token 然后将 token 传递给需要授权的第二种方法的完整单元测试:

[TestMethod]

public void GetAuthorizedStatus_SelfHostedHTTP()
{
    HttpServer server = TestAPIHelper.GenerateTestServer();

    using (HttpMessageInvoker client = new HttpMessageInvoker(server))
    {
        string token = string.Empty;

        using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, loginURL))
        {
            var stringContent = new StringContent(JsonConvert.SerializeObject(TestAPIHelper.loginObject), Encoding.UTF8, "application/json");
            request.Content = stringContent;

            using (HttpResponseMessage response = client.SendAsync(request, System.Threading.CancellationToken.None).Result)
            {
                Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Error getting token from login portion");

                token = response.Content.ReadAsAsync<string>().Result;
                Assert.IsTrue(token.Length > 50);
            }
        }

        using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, authorizedStatusURL))
        {
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

            using (HttpResponseMessage response = client.SendAsync(request, System.Threading.CancellationToken.None).Result)
            {
                Assert.AreEqual(HttpStatusCode.OK, response.StatusCode, "Error getting status from Authenticated portion.");
            }
        }
    };
}

问题是 TokenValidationHandler 抛出“未将对象引用设置为对象的实例”。处理程序的以下两行中的第二行异常,仅当我的单元测试调用并附加 token 时。如果我使用 ReSTLet/Postman/whatever 触发处理程序,则不会引发异常并且一切正常。
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);

当第一行几乎相同的行工作时,我不明白是什么导致仅第二行出错 - 两行调用相同的方法。而且我不明白为什么它适用于第三方软件但不适用于我的测试代码 - 我担心的是,如果我不为单元测试弄清楚这一点,那么我将无法使代码适用于调用此 api 的真实应用程序。我认为这是我的测试代码中的一些微不足道的设置,我需要在提交之前添加到我的请求中。但也许我需要构建一种完全不同的方法来在我的单元测试中调用 API。

最佳答案

我不会这样做。
在这种情况下,我所做的是编写涵盖 token 逻辑的集成测试。
这意味着调用 token 端点,检索 token ,然后调用其他内容并查看会发生什么。
然后,您可以添加其他测试,例如当 token 丢失、无效、过期或包含错误声明时会发生什么。

关于c# - 使用 Web API 对 JWT token 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51353294/

相关文章:

c# - 结构中对齐不正确/非对象字段

c# - 使用变量引用对象 (c#)

java - EclEmma(Jacoco) 显示未覆盖的行,即使该行已执行

c# - 如何在 iOS Xamarin C# 中设置本地化/文化

c# - 登录失败,因为 AudienceUris 中不存在指定的受众

Android Studio,Junit4加入classpath后仍无法解析Junit

android - 在 android Test 文件夹中创建 Dummy Activity 进行测试

javascript - Web Api 属性路由无法访问带有问号和与号的数据的方法

json - 调用 Web API 2 端点时出现 HTTP 415 不支持的媒体类型错误

cookies - 如何使用 OWIN 在 Web API 中组合 OAuth 和 cookie 身份验证?