poc*_*sov 9 testing cookies owin asp.net-core-mvc asp.net-core
有没有简单的方法来得到一个访问CookieContainer的response对象中运行集成测试用AspNet.TestHost.TestServer.Cookie必须由控制器操作设置.实现这一目标的最佳方法是什么?
var client = TestServer.Create(app =>
{
app.UseMvc(routes =>
routes.MapRoute("default", "{controller}/{action}/{id?}"));
app.UseIdentity();
}).CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, "account/login");
var response = await client.SendAsync(request);
// how to get an access to cookie container ?????????
// response.Cookies prop doesn't exist
Assert.NotEmpty(response.Cookies["auth"]);
Run Code Online (Sandbox Code Playgroud)
我看到的解决方案是扩展TestServer的实例,返回类的实例CustomClientHandler : ClientHandler并覆盖在该处理程序中发送请求的整个过程,但除了相对较小的TestServer代码之外,它还需要改变所有逻辑.
有没有更好的建议如何在响应中实现对Cookie的访问?
作为 @Oleh 响应的补充,您可以实现相同的目标,而无需反思 .NET 4.6.1+ / .NET Core 等较新的框架
public class TestHttpClientHandler : DelegatingHandler
{
[NotNull]
private readonly CookieContainer cookies = new CookieContainer();
public TestHttpClientHandler([NotNull] HttpMessageHandler innerHandler)
: base(innerHandler) { }
[NotNull, ItemNotNull]
protected override async Task<HttpResponseMessage> SendAsync([NotNull] HttpRequestMessage request, CancellationToken ct)
{
Uri requestUri = request.RequestUri;
request.Headers.Add(HeaderNames.Cookie, this.cookies.GetCookieHeader(requestUri));
HttpResponseMessage response = await base.SendAsync(request, ct);
if (response.Headers.TryGetValues(HeaderNames.SetCookie, out IEnumerable<string> setCookieHeaders))
{
foreach (SetCookieHeaderValue cookieHeader in SetCookieHeaderValue.ParseList(setCookieHeaders.ToList()))
{
Cookie cookie = new Cookie(cookieHeader.Name.Value, cookieHeader.Value.Value, cookieHeader.Path.Value);
if (cookieHeader.Expires.HasValue)
{
cookie.Expires = cookieHeader.Expires.Value.DateTime;
}
this.cookies.Add(requestUri, cookie);
}
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经实现了跟踪 cookie 的自定义 HttpMessageHandler。
它使用反射来调用实际的处理程序并仅读取/设置 Cookie 标头。
class TestMessageHandler : HttpMessageHandler
{
delegate Task<HttpResponseMessage> HandlerSendAsync(HttpRequestMessage message, CancellationToken token);
private readonly HandlerSendAsync nextDelegate;
private readonly CookieContainer cookies = new System.Net.CookieContainer();
public TestMessageHandler(HttpMessageHandler next)
{
if(next == null) throw new ArgumentNullException(nameof(next));
nextDelegate = (HandlerSendAsync)
next.GetType()
.GetTypeInfo()
.GetMethod("SendAsync", BindingFlags.NonPublic | BindingFlags.Instance)
.CreateDelegate(typeof(HandlerSendAsync), next);
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("Cookie", cookies.GetCookieHeader(request.RequestUri));
var resp = await nextDelegate(request, cancellationToken).ConfigureAwait(false);
if (resp.Headers.TryGetValues("Set-Cookie", out var newCookies))
{
foreach (var item in SetCookieHeaderValue.ParseList(newCookies.ToList()))
{
cookies.Add(request.RequestUri, new Cookie(item.Name, item.Value, item.Path));
}
}
return resp;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你像这样创建 HttpClient:
var httpClient = new HttpClient(
new TestMessageHandler(
server.CreateHandler()));
Run Code Online (Sandbox Code Playgroud)
TestMessageHandler 现在负责跟踪 cookie。
| 归档时间: |
|
| 查看次数: |
2396 次 |
| 最近记录: |