HttpClient 默认 headers 不适用于 Microsoft.Owin.Testing.TestServer
HttpClient default headers not working with Microsoft.Owin.Testing.TestServer
我正在使用 Microsoft.Owin.Testing
库来集成测试我的 API in-memory。我已经在 OWIN JWT 中间件中添加了我的身份验证需求,现在正尝试将生成的令牌传递给需要授权的控制器以测试请求。我可以向您保证 JWT 中间件设置正确,因为它在正常使用时工作正常。但是,我观察到 TestServer.HttpClient
object 有一些奇怪的行为。当我在 HttpClient 上设置默认授权 header 以传递令牌时,我的测试从未通过,因为无法识别令牌。但是,当我使用 TestServer.CreateRequest(...)
时,测试正确通过并且令牌被识别。我更愿意使用 HttpClient 方法,因为它们通过提供的所有扩展方法(例如 PostAsJsonAsync
等)使事情变得容易得多。我开始认为 [=15] 中存在错误=] 或者我完全遗漏了一些东西。
这是我的测试 class(使用 NUnit3):
public class DefinitionsControllerTests
{
private TestServer _server;
private string _accessToken;
[SetUp]
public void Setup()
{
_server = TestServer.Create<Startup>();
var credentials = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "john.doe@mail.com"),
new KeyValuePair<string, string>("password", "testing123")
});
// get token from OWIN JWT middleware
dynamic resultBody = JObject.Parse(
_server.HttpClient.PostAsync("/oauth/token", credentials).Result.Content.ReadAsStringAsync().Result);
_accessToken = (string)resultBody.access_token;
// this does not appear to ever work
_server.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
}
[TearDown]
public void TearDown()
{
_server.Dispose();
}
[Test]
public void GetById_WithExistingId()
{
// 401 Unauthorized response everytime and test fails
var response = _server.HttpClient.GetAsync($"/api/definitions/{expected.Id}").Result;
var actual = response.Content.ReadAsAsync<Definition>().Result;
// 200 Ok every time and test passes
// - these variables aren't part of the test but rather to show alternate request creation method that works
var response2 = _server.CreateRequest($"/api/definitions/{expected.Id}")
.AddHeader("Authorization", "Bearer " + _accessToken)
.GetAsync()
.Result;
var actual2 = response.Content.ReadAsAsync<Definition>().Result;
response.StatusCode.ShouldBe(HttpStatusCode.OK);
actual.ShouldNotBeNull();
}
//...other test methods
}
还有我的控制器:
[Authorize]
public class DefinitionsController : ApiController
{
private readonly IDefinitionRepository _repo;
public DefinitionsController(IDefinitionRepository repo)
{
_repo = repo;
}
public IHttpActionResult Get(Guid id)
{
var definition = _repo.Get(id);
if (definition == null)
return NotFound();
return Ok(definition);
}
}
有人知道为什么只有 CreateRequest() 有效吗?这有点令人气愤。
问题是 HttpClient 属性 returns 每次都是一个新实例。如果您保存该实例并重新使用它,它将起作用。
https://github.com/aspnet/AspNetKatana/blob/b850cd8b4de61e65bbd7127ce02b5df7c4cb6db5/src/Microsoft.Owin.Testing/TestServer.cs#L48
我正在使用 Microsoft.Owin.Testing
库来集成测试我的 API in-memory。我已经在 OWIN JWT 中间件中添加了我的身份验证需求,现在正尝试将生成的令牌传递给需要授权的控制器以测试请求。我可以向您保证 JWT 中间件设置正确,因为它在正常使用时工作正常。但是,我观察到 TestServer.HttpClient
object 有一些奇怪的行为。当我在 HttpClient 上设置默认授权 header 以传递令牌时,我的测试从未通过,因为无法识别令牌。但是,当我使用 TestServer.CreateRequest(...)
时,测试正确通过并且令牌被识别。我更愿意使用 HttpClient 方法,因为它们通过提供的所有扩展方法(例如 PostAsJsonAsync
等)使事情变得容易得多。我开始认为 [=15] 中存在错误=] 或者我完全遗漏了一些东西。
这是我的测试 class(使用 NUnit3):
public class DefinitionsControllerTests
{
private TestServer _server;
private string _accessToken;
[SetUp]
public void Setup()
{
_server = TestServer.Create<Startup>();
var credentials = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", "john.doe@mail.com"),
new KeyValuePair<string, string>("password", "testing123")
});
// get token from OWIN JWT middleware
dynamic resultBody = JObject.Parse(
_server.HttpClient.PostAsync("/oauth/token", credentials).Result.Content.ReadAsStringAsync().Result);
_accessToken = (string)resultBody.access_token;
// this does not appear to ever work
_server.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
}
[TearDown]
public void TearDown()
{
_server.Dispose();
}
[Test]
public void GetById_WithExistingId()
{
// 401 Unauthorized response everytime and test fails
var response = _server.HttpClient.GetAsync($"/api/definitions/{expected.Id}").Result;
var actual = response.Content.ReadAsAsync<Definition>().Result;
// 200 Ok every time and test passes
// - these variables aren't part of the test but rather to show alternate request creation method that works
var response2 = _server.CreateRequest($"/api/definitions/{expected.Id}")
.AddHeader("Authorization", "Bearer " + _accessToken)
.GetAsync()
.Result;
var actual2 = response.Content.ReadAsAsync<Definition>().Result;
response.StatusCode.ShouldBe(HttpStatusCode.OK);
actual.ShouldNotBeNull();
}
//...other test methods
}
还有我的控制器:
[Authorize]
public class DefinitionsController : ApiController
{
private readonly IDefinitionRepository _repo;
public DefinitionsController(IDefinitionRepository repo)
{
_repo = repo;
}
public IHttpActionResult Get(Guid id)
{
var definition = _repo.Get(id);
if (definition == null)
return NotFound();
return Ok(definition);
}
}
有人知道为什么只有 CreateRequest() 有效吗?这有点令人气愤。
问题是 HttpClient 属性 returns 每次都是一个新实例。如果您保存该实例并重新使用它,它将起作用。 https://github.com/aspnet/AspNetKatana/blob/b850cd8b4de61e65bbd7127ce02b5df7c4cb6db5/src/Microsoft.Owin.Testing/TestServer.cs#L48