我想用填充的数据创建一个HttpRequest实例,这样我就可以测试一个方法。
我需要将Microsoft.AspNetCore.Http.HttpRequest作为参数传递给函数。
如何实例化它?
[Route("/summary/{id}")]
public IActionResult Account(int id)
{
var summary = RequestHelper.ParseRequest(Request);
}
选项来自程序包https://github.com/louthy/language-ext
public static Option<SummaryRequest> ParseRequest(HttpRequest request)
{
if (request== null)
{
var query = request.Query;
var result = new SummaryRequest();
var locations = ExtractData(query, "location");
var categories = ExtractData(query, "categories[]");
var titles = ExtractData(query, "titles");
}
}
public static Option<SummaryRequest> ParseRequest(HttpRequest request)
{
if (request== null)
{
var query = request.Query;
var result = new SummaryRequest();
var locations = ExtractData(query, "location");
var categories = ExtractData(query, "categories[]");
var titles = ExtractData(query, "titles");
}
return new SummaryRequest();
}
public static Either<Exception, string[]> ExtractData(IEnumerable<KeyValuePair<String, StringValues>> query, string filter)
{
try
{
return query.First(x => x.Key.ToLower() == filter).Value.ToString().Split(',').ToArray();
}
catch (Exception ex)
{
return ex;
}
}
单元测试示例
[TestMethod]
[TestCategory(Test.RequestParser)]
public void ParseRequest_WithHttpRequest_ReturnResultOnSuccess()
{
// var request = this doesn't compile I need an instance of
// Microsoft.AspNetCore.Http.HttpRequest
var result = Helper.ParseRequest(request);
}
您可以使用DefaultHttpContext
的Request
属性。这有点复杂,因为你必须单独指定很多属性(与例如WebRequest.Create
相比(,但以下对我有效:
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "POST";
httpContext.Request.Scheme = "http";
httpContext.Request.Host = new HostString("localhost");
httpContext.Request.ContentType = "application/json";
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
await writer.WriteAsync("{}");
await writer.FlushAsync();
stream.Position = 0;
httpContext.Request.Body = stream;
Glorfindel的答案,尽管对于大多数场景来说已经足够好了,但在关键的场景中失败了:默认的HttpRequestStream
是Request.Body
下面的原始流,它是"仅向前";如果你想读两遍,你需要使用HttpContext.Request.EnableBuffering()
。
现在的问题是,如何在测试场景中复制这一点?:我创建了一个存根实现:
internal sealed class HttpRequestStreamStub : MemoryStream
{
public HttpRequestStreamStub() { }
public HttpRequestStreamStub(byte[] buffer) : base(buffer) { }
public override bool CanSeek => false;
public override bool CanRead => true;
public override bool CanWrite => false;
public override long Length => throw new NotSupportedException();
public override long Position
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override int WriteTimeout
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
=> throw new NotSupportedException();
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> throw new NotSupportedException();
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
=> throw new NotSupportedException();
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
}
它尽可能最好地复制https://github.com/dotnet/aspnetcore/blob/main/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs