Home > database >  How do I replicate HttpRequest
How do I replicate HttpRequest

Time:09-17

PayPal have provided example code how to receive a notification of a purchase (or similar). Sadly, I don't see a way to manually test this and I'm struggling to see how to replicate Microsoft.AspNetCore.Http HttpRequest

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

The relevant part of the code is

[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
}

What I'd like to do is replicate request so I can execute this from a test! Normally, I'd refactor the code so I can pass parameters to get around this issue (even if I pass in the rendered string).

In this instance, I want to pretend I can't touch the source code, but still need to test it. This is so I can learn more.

As the bit I am after is the stream, as seen in ipnContext.IPNRequest.Body, I'm stumped. If it's a stream, I can't assign it as a string, but when it does the ReadToEndAsync, a string comes out!

How do I create the Request object with a similar shape to what PayPal expects for Request.IPNRequest.Body

CodePudding user response:

Arrange a stream as needed and pass that to the controller via the 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
}

The sample code linked to your original example is tightly coupled to external dependencies and may have other issues that are outside of the scope of what was originally asked.

  • Related