Search code examples
httpwebrequestservicestackhttprequest

Can I test form data using `HttpResultsFilter` callback?


In a ServiceStack project I am trying to test the following application code:

var formData = "client_id={0}".Fmt(ClientId);
var contents = AccessTokenUrl.PostToUrl(formData);

ServiceStack provides the HttpResultFilter for mocking the PostToUrl utility function.

My test uses that as follows:

using (new HttpResultsFilter
{
    StringResultFn = (HttpWebRequest tokenRequest) =>
    {
        tokenRequest.RequestUri.ToString().Should().Be(
            "https://example.com/auth/token");
        tokenRequest.Method.Should().Be("POST");
        tokenRequest.ContentType.Should().Be("application/x-www-form-urlencoded");
        // TODO: Test form data
        //formData["client_id"].Should().Be(Subject.ClientId);

How can I access the form data in the request for verification?


Solution

  • From v4.0.50 to improve the usefulness of mocking HTTP Requests, the request body is now passed in the Results Filter so the Request Body can be inspected, e.g:

    using (new HttpResultsFilter
    {
        StringResultFn = (webReq, reqBody) =>
        {
            if (reqBody != null && reqBody.Contains("{\"a\":1}")) 
                return "mocked-by-body";
    
            return webReq.RequestUri.ToString().Contains("google")
                ? "mocked-google"
                : "mocked-yahoo";
        }
    })
    {
        "http://yahoo.com".PostJsonToUrl(json: "{\"a\":1}") //= mocked-by-body
    
        "http://google.com".GetJsonFromUrl() //= mocked-google
        "http://yahoo.com".GetJsonFromUrl()  //= mocked-yahoo
    }
    

    Prior to v4.0.50 this wasn't possible since POST'ed data gets written to the HttpWebRequest ConnectStream which is an internal write-only Stream where attempting to read from it will throw an exception.