我如何复制 HttpRequest

How do I replicate HttpRequest

PayPal 提供了如何接收购买通知(或类似通知)的示例代码。可悲的是,我没有找到手动测试的方法,我正在努力寻找如何复制 Microsoft.AspNetCore.Http HttpRequest

https://github.com/paypal/ipn-code-samples/tree/master/C%23

代码的相关部分是

[HttpPost]
public IActionResult Receive()
{
    IPNContext ipnContext = new IPNContext()
    {
        IPNRequest = Request      //IPNRequest is HttpRequest 
    };

    using (var reader = new StreamReader(ipnContext.IPNRequest.Body, Encoding.ASCII))
    {
        ipnContext.RequestBody = await reader.ReadToEndAsync();
    }
    //other code removed for this example
}

我想做的是复制 request 这样我就可以从测试中执行它!通常,我会重构代码,以便我可以传递参数来解决这个问题(即使我传递了呈现的字符串)。

在这种情况下,我想假装我不能接触源代码,但仍然需要测试它。这样我就可以学到更多。

因为我所追求的是 stream,如 ipnContext.IPNRequest.Body 中所示,我很难过。如果它是一个流,我不能将它分配为一个字符串,但是当它分配给 ReadToEndAsync 时,一个字符串就出来了!

如何创建形状与 PayPal 期望的形状相似的 Request 对象 Request.IPNRequest.Body

根据需要安排流并通过 HttpContext.Request

将其传递给控制器
[TestMethod]
public Task Should_Receive() {
    //Arrange
    var data = "My paypal expected string here";
    var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(data));

    HttpContext httpContext = new DefaultHttpContext();
    httpContext.Request.Body = stream; //<-- Setting request BODY here
    httpContext.Request.ContentLength = stream.Length;

    var controller = new IPNController {
        ControllerContext = new ControllerContext() {
            HttpContext = httpContext,
        }
    };

    //Act
    IActionResult result = await controller.Receive();

    //Assert
    //assert as needed
}

链接到您的原始示例的示例代码与外部依赖项紧密耦合,可能存在超出最初要求范围的其他问题。