如何创建Microsoft.AspNetCore.Http.HttpRequest实例进行测试



我想用填充的数据创建一个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);
}

您可以使用DefaultHttpContextRequest属性。这有点复杂,因为你必须单独指定很多属性(与例如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的答案,尽管对于大多数场景来说已经足够好了,但在关键的场景中失败了:默认的HttpRequestStreamRequest.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

最新更新