Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace Mockly
public Mockly.RequestMockBuilder ForPut(string urlPattern) { }
public System.Net.Http.HttpClient GetClient() { }
public System.Net.Http.IHttpClientFactory GetClientFactory() { }
public System.Net.Http.HttpMessageHandler GetMessageHandler() { }
public System.Collections.Generic.IEnumerable<Mockly.RequestMock> GetUninvokedMocks() { }
public Mockly.HttpMock Reset() { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace Mockly
public Mockly.RequestMockBuilder ForPut(string urlPattern) { }
public System.Net.Http.HttpClient GetClient() { }
public System.Net.Http.IHttpClientFactory GetClientFactory() { }
public System.Net.Http.HttpMessageHandler GetMessageHandler() { }
public System.Collections.Generic.IEnumerable<Mockly.RequestMock> GetUninvokedMocks() { }
public Mockly.HttpMock Reset() { }
}
Expand Down
21 changes: 21 additions & 0 deletions Mockly.Specs/HttpMockSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,27 @@
}
}

public class WhenGettingMessageHandler
{
[Fact]
public async Task Can_return_a_message_handler_that_intercepts_requests()
{
var mock = new HttpMock();
mock.ForGet().WithPath("/ping").RespondsWithStatus(HttpStatusCode.OK);

var handler = mock.GetMessageHandler();

using var client = new HttpClient(handler)

Check warning

Code scanning / InspectCode

Do not use object initializer for 'using' variable: Do not use object initializer for 'using' variable Warning

Initialize object properties inside the 'using' statement to ensure that the object is disposed if an exception is thrown during initialization
{
BaseAddress = new Uri("https://localhost/")
};

var response = await client.GetAsync("/ping");

response.Should().Be200Ok();
}
}

public class RespondingWithHttpContent
{
[Fact]
Expand Down
12 changes: 12 additions & 0 deletions Mockly/HttpMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ public IHttpClientFactory GetClientFactory()
return new MockHttpClientFactory(this);
}

/// <summary>
/// Gets the underlying <see cref="HttpMessageHandler"/> that intercepts HTTP requests based on the configured mocks.
/// Use this when you need to wire the mock handler directly into an <see cref="HttpClient"/> or other infrastructure
/// that accepts an <see cref="HttpMessageHandler"/>.
/// </summary>
[SuppressMessage("Design", "CA1024:Use properties where appropriate",
Justification = "GetMessageHandler creates resources and should not be a property")]
public HttpMessageHandler GetMessageHandler()
{
return new MockHttpMessageHandler(this);
}

internal void AddMock(RequestMock mock)
{
mocks.Add(mock);
Expand Down
15 changes: 15 additions & 0 deletions website/docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ var response = await client.GetAsync("/ping");
response.StatusCode.Should().Be(HttpStatusCode.OK);
```

## Using a Raw HttpMessageHandler

If your code accepts an `HttpMessageHandler` directly (for example, when constructing `HttpClient` yourself or integrating with custom infrastructure), Mockly can provide the underlying handler:

```csharp
var mock = new HttpMock();
mock.ForGet().WithPath("/ping").RespondsWithStatus(HttpStatusCode.OK);

HttpMessageHandler handler = mock.GetMessageHandler();
var client = new HttpClient(handler) { BaseAddress = new Uri("https://localhost/") };

var response = await client.GetAsync("/ping");
response.StatusCode.Should().Be(HttpStatusCode.OK);
```

## Complete Example

Here's a more comprehensive example showing multiple features:
Expand Down
21 changes: 21 additions & 0 deletions website/docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ mock.ForGet()
HttpClient client = mock.GetClient(); // BaseAddress defaults to https://localhost/
```

## Getting an HttpClient, IHttpClientFactory or HttpMessageHandler

Mockly provides three ways to wire the mock into your code under test:

- **`GetClient()`** — returns a new `HttpClient` with `BaseAddress` set to `https://localhost/`, ready to use directly in tests.
- **`GetClientFactory()`** — returns an `IHttpClientFactory` whose `CreateClient()` method produces `HttpClient` instances backed by the mock. Use this when your code depends on `IHttpClientFactory`.
- **`GetMessageHandler()`** — returns the underlying `HttpMessageHandler`. Use this when you need to build a custom `HttpClient` or pass the handler to other infrastructure.

```csharp
// Option 1: HttpClient (BaseAddress defaults to https://localhost/)
HttpClient client = mock.GetClient();

// Option 2: IHttpClientFactory
IHttpClientFactory factory = mock.GetClientFactory();
HttpClient clientFromFactory = factory.CreateClient("myClient");

// Option 3: HttpMessageHandler
HttpMessageHandler handler = mock.GetMessageHandler();
var customClient = new HttpClient(handler) { BaseAddress = new Uri("https://localhost/") };
```

## HTTP Method Support

Mockly supports all common HTTP methods:
Expand Down
Loading