HttpRequestSpy 0.0.24

Suggested Alternatives

HttpRequest.Spy

Additional Details

HttpRequestSpy has been renamed to HttpRequest.Spy

dotnet add package HttpRequestSpy --version 0.0.24                
NuGet\Install-Package HttpRequestSpy -Version 0.0.24                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HttpRequestSpy" Version="0.0.24" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add HttpRequestSpy --version 0.0.24                
#r "nuget: HttpRequestSpy, 0.0.24"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install HttpRequestSpy as a Cake Addin
#addin nuget:?package=HttpRequestSpy&version=0.0.24

// Install HttpRequestSpy as a Cake Tool
#tool nuget:?package=HttpRequestSpy&version=0.0.24                

HttpRequestSpy

example workflow

HttpRequestSpy is a tool aiming to test outgoing HttpRequest sent via an HttpClient.

It compares all sent http requests to an expected request definition and provides a user friendly error message when no recorded httprequest matches the expected one.

This tool is useful when you want to test your outgoing http requests but you don't want to mock the http client.

Installation

dotnet add package HttpRequestSpy

Usage

    [Fact]
    public async Task HttpRequest_should_be_sent()
    {
        // Arrange
        var spy = HttpRequestSpy.Create();
        using var httpClient = new HttpClient(new SpyHttpMessageHandler(spy));

        var instance = new TypedHttpClient(httpClient);

        // Act
        await instance.MakeHttpRequest();

        // Assert
        spy.HasRecordedRequests(1);

        spy.AGetRequestTo("/some/ressource")
           .WithQuery(new {
               id = "12"
           })
           .OccurredOnce();
    }


    public class TypedHttpClient(HttpClient httpClient) {
        public async Task<HttpResponseMessage> MakeHttpRequest() {
            return await httpClient.GetAsync("/some/ressource?id=12");
        }
    }

Features

Fluent API

The HttpRequestSpy provides a fluent API to help you define your expected http request.

    spy.AGetRequestTo("/some/ressource")
       .WithQuery(new {
           id = "12"
       })
       .OccurredOnce();

User friendly error messages

One of the main idea behind this tool is to provide a user friendly error message when no recorded http request matches the expected one.

    spy.APostRequestTo("/some/resource")
        .WithJsonPayload(new {
            prop1 = 1
        })
        .WithQuery(new {
            id = "12"
        })
        .OccurredOnce();
 ⚠ Unexpected number of recorded requests matching expectations. Expected : 1. Actual : 0

Expectations: 
 ✔ Method : POST
 ✔ Expected URL : /some/resource
 ✔ Payload : {"prop1":1}
 ✔ Query { id = 12 }

2 Recorded requests: 
0/ GET http://domain/path/to/resource
  ⚠ HttpMethod does not match:
 - Expected : POST
 - Actual : GET
  ⚠ URL does not match:
 - Expected : /some/resource
 - Actual : /path/to/resource
  ⚠ Payload is empty:
 - Expected : {"prop1":1}
 - Actual : [null]
  ⚠ Query does not match :
   -> Missing property $.id

1/ POST http://domain/path/to/resource
  ⚠ URL does not match:
 - Expected : /some/resource
 - Actual : /path/to/resource
  ⚠ Payload is empty:
 - Expected : {"prop1":1}
 - Actual : [null]
  ⚠ Query does not match :
   -> Missing property $.id

Occurrences

You can define the number of occurences of your expected request.

    spy.AGetRequestTo("/some/ressource")
       .OccurredOnce();

    spy.AGetRequestTo("/some/ressource")
       .OccurredTwice();

    spy.AGetRequestTo("/some/ressource")
       .Occurred(3);
    
    spy.AGetRequestTo("/some/ressource")
       .NeverOccurred();

Number of overall recorded requests

You can define the number of overall recorded requests.

    spy.HasRecordedRequests(5);
       .NeverOccurred();

This codes checks that 5 requests have been recorded regardless of the content of the requests.

Absolute path and relative url

You can define the absolute path or the relative url of your expected request.

    spy.AGetRequestTo("/some/ressource")
       .OccurredOnce();
    spy.AGetRequestTo("https://myapi.com/some/ressource")
       .OccurredOnce();

GET, POST, PUT, DELETE, PATCH http verbs

You can define the http verb of your expected request.

    spy.AGetRequestTo("/some/ressource")
       .OccurredOnce();
    
    spy.APostRequestTo("/some/ressource")
       .OccurredOnce();
    
    spy.APutRequestTo("/some/ressource")
       .OccurredOnce();
    
    spy.APatchRequestTo("/some/ressource")
       .OccurredOnce();
    
    spy.ADeleteRequestTo("/some/ressource")
       .OccurredOnce();

Query parameters

You can define the query parameters of your expected request as an anonymous object.

    spy.AGetRequestTo("/some/ressource")
       .WithQuery(new {
           id = "12",
           date = "2024-01-05"
       })
        /// Or
       .WithQuery("id=12&date=2024-01-05")
        /// Or
       .WithQueryParam("id", "12")
       .WithQueryParam("date", "2024-01-05")
        
       .OccurredOnce();

Body / Payload

Only for POST, PUT, PATCH requests

You can define the body of your expected request as an anonymous object or target a specific property.

Check Json payload

See HttpRequestSpyWhenJsonPayloadShould.cs file for all use cases.

    spy.APostRequestTo("/some/ressource")       
       .WithJsonPayload(new
                    {
                        prop1 = 1,
                        prop2 = "value",
                        subProp = new
                        {
                            subProp1 = "subValue"
                        }
                    })
        
        // Or
        .WithJsonPayloadProperty("prop1") // Will check that the property exists
        .WithJsonPayloadProperty("prop1", 1)
        .WithJsonPayloadProperty("prop2", "value")
        .WithJsonPayloadProperty("subProp", new
                        {
                            subProp1 = "subValue"
                        })
        
        
       .OccurredOnce();
Json payload matching JsonSchema

Using JsonSchema, you can check that the payload matches a specific schema.

    spy.APostRequestTo("/some/ressource")       
        .WithPayloadMatchingJsonSchema("path/to/schema.json")
       .OccurredOnce();
Check Xml payload

See HttpRequestSpyWhenXmlPayloadShould.cs file for all use cases.

    spy.APostRequestTo("/some/ressource")
       .WithXmlPayload(new
                    {
                        prop1 = 1,
                        prop2 = "value",
                        subProp = new
                        {
                            subProp1 = "subValue"
                        }
                    })
        
        // Or
        .WithXmlPayloadProperty("/_x003F_anonymous_x003F_/prop1") // Will check that the property exists
        .WithXmlPayloadProperty("/_x003F_anonymous_x003F_/prop1", 1)
        .WithXmlPayloadProperty("/_x003F_anonymous_x003F_/prop2", "value")
        .WithXmlPayloadProperty("/_x003F_anonymous_x003F_/subProp", new
                        {
                            subProp1 = "subValue"
                        })
        // Or  :
        .WithXmlPayloadProperty("/_x003F_anonymous_x003F_/subProp/subProp1", "subValue")
        
        
       .OccurredOnce();
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.0.24 145 1/5/2024 0.0.24 is deprecated.
0.0.23 131 1/5/2024 0.0.23 is deprecated.
0.0.20 136 1/5/2024 0.0.20 is deprecated.