diff --git a/README.md b/README.md
index aaf5c8b..3953dcc 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,9 @@
[](https://coveralls.io/github/Adolfok3/Fresp?branch=main)
[](https://www.nuget.org/packages/fresp)
-# Fresp
+# Fresp - Fake Responses
-Fresp (shorthand for `fake response`) is a .NET package that provides a way to mock API responses through your `HttpClient` during application execution. It allows you to configure both synchronous and asynchronous fake responses based on the incoming `HttpRequestMessage`.
+Fresp (shorthand for `fake response`) is a .NET package based on `DelegatingHandler` that provides a way to mock API responses through your `HttpClient` during application execution. It allows you to configure both synchronous and asynchronous fake responses based on the incoming `HttpRequestMessage` or `HttpResponseMessage`.
## Problem
@@ -21,7 +21,7 @@ The Fresp package helps to solve this problem by allowing developers to configur
> Fresp is not intended for unit testing; it is recommended for use in UAT, QA, and development environments during execution.
> [!WARNING]
-> By default, Fresp is disabled in the production environment, so the chance of getting a fake response in production is zero! Unless your `ASPNETCORE_ENVIRONMENT` variable is wrong set in production server!
+> Fresp has a guard to avoid execution in the production environment, so the chance of getting a fake response in production is zero! Unless your `ASPNETCORE_ENVIRONMENT` variable is incorrectly set on the production server...
## Installation
@@ -43,27 +43,35 @@ dotnet add package Fresp
### Adding Fake Response to your HttpClient
-To make `Fresp` mock and return fake responses from your `HttpClient`, use the `AddFakeResponseHandler` extension method:
+To make `Fresp` mock and return fake responses from your `HttpClient`, use the `AddFakeHandler` extension method:
```csharp
services.AddHttpClient("MyClient")
- .AddFakeResponseHandler(options =>
+ .AddFakeHandler(options =>
{
- options.Enabled = true; // Toggle fake responses for this client. It is recommended to use this in conjunction with configuration settings from appsettings.json.
+ options.Enabled = true; // Toggle fake responses for this client. It is recommended to use this in conjunction with configuration settings from appsettings.json to enable/disable easily
});
```
### Configuring Fake Responses
-Use the method `AddFakeResponse` for synchronous request calls or `AddFakeResponseAsync` for asynchronous request calls:
+There are two ways to return fake responses, `FromRequest` and `FromResponse`:
+
+- **FromRequest**: will return a fake response before the request is sent to the target API, if the request predicate is matched.
+
+- **FromResponse**: will return a fake response after the request was sent to the target API, if the response predicate is matched.
+
+#### Fake responses from request
+
+To add a fake response from a request, use the method `AddFakeResponseFromRequest` for synchronous request calls or `AddFakeResponseFromRequestAsync` for asynchronous request calls:
- Synchronous:
```csharp
services.AddHttpClient("MyClient")
- .AddFakeResponseHandler(options =>
+ .AddFakeHandler(options =>
{
options.Enabled = true;
- options.AddFakeResponse(request =>
+ options.AddFakeResponseFromRequest(request =>
{
if (request.RequestUri?.AbsolutePath == "/endpoint")
{
@@ -79,10 +87,10 @@ services.AddHttpClient("MyClient")
- Asynchronous:
```csharp
services.AddHttpClient("MyClient")
- .AddFakeResponseHandler(options =>
+ .AddFakeHandler(options =>
{
options.Enabled = true;
- options.AddFakeResponseAsync(async request =>
+ options.AddFakeResponseFromRequestAsync(async request =>
{
var body = await request.Content.ReadAsStringAsync();
if (body.Contains("something"))
@@ -98,7 +106,102 @@ services.AddHttpClient("MyClient")
});
```
-If the request predicate is matched, the following configured response will be returned. It's simple and lightweight!
+#### Fake responses from response
+
+If you need to add a fake response from a response, use the method `AddFakeResponseFromResponse` for synchronous request calls or `AddFakeResponseFromResponseAsync` for asynchronous request calls:
+
+- Synchronous:
+```csharp
+services.AddHttpClient("MyClient")
+ .AddFakeHandler(options =>
+ {
+ options.Enabled = true;
+ options.AddFakeResponseFromResponse(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent("Sync fake response")
+ };
+ }
+ return null;
+ });
+ });
+```
+- Asynchronous:
+```csharp
+services.AddHttpClient("MyClient")
+ .AddFakeHandler(options =>
+ {
+ options.Enabled = true;
+ options.AddFakeResponseFromResponse(async response =>
+ {
+ var body = await response.Content.ReadAsStringAsync();
+ if (body.Contains("something"))
+ {
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent("Async fake response")
+ };
+ }
+
+ return await Task.FromResult(null);
+ });
+ });
+```
+
+### Tips
+
+#### Mock API
+Fresp is a nice way to create mock APIs to test API calls during execution (similar to [WireMock-Net](https://github.com/WireMock-Net/WireMock.Net)). Just create a random `HttpClient` and configure the fake responses:
+
+```csharp
+services.AddHttpClient("FakeHttpClient")
+ .AddFakeHandler(options =>
+ {
+ // Configure your fake responses...
+ })
+ .ConfigureHttpClient(c => c.BaseAddress = new Uri("http://this-api-does-not-exist.com"));
+```
+
+#### Multiple Fake Responses
+
+Sometimes you can have a lot of `FromRequest` and `FromResponse` fakes configured in options. To make it cleaner, you can use classes that implement some of the interfaces: `IFakeResponseFromRequest`, `IFakeResponseFromRequestAsync`, `IFakeResponseFromResponse`, and `IFakeResponseFromResponseAsync`. E.g.:
+
+Your fake response class:
+```csharp
+public class MyFakeResponseClass : IFakeResponseFromRequestAsync
+{
+ public Func> GetFakeResponseFromRequestAsync()
+ {
+ return async request =>
+ {
+ if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake-2") && request.Method == HttpMethod.Get)
+ {
+ return await Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ });
+ }
+
+ return await Task.FromResult((HttpResponseMessage?)null);
+ };
+ }
+}
+```
+
+In the options configuration:
+```csharp
+services.AddHttpClient("MyClient")
+ .AddFakeHandler(options =>
+ {
+ options.Enabled = true;
+ options.AddFakeResponseFromRequestAsync();
+ });
+```
## License
diff --git a/src/FakeHandler.cs b/src/FakeHandler.cs
new file mode 100644
index 0000000..6e54322
--- /dev/null
+++ b/src/FakeHandler.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Fresp;
+
+internal class FakeHandler(FakeOptions options, string clientName, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory) : DelegatingHandler
+{
+ private readonly ILogger _logger = loggerFactory.CreateLogger(nameof(FakeHandler));
+ private readonly bool _isProduction = hostEnvironment.IsProduction();
+
+ protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
+ => !UseFakeHandler()
+ ? base.Send(request, cancellationToken)
+ : SendWithFakeResponseFromRequest(request, cancellationToken);
+
+ protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ => !UseFakeHandler()
+ ? await base.SendAsync(request, cancellationToken)
+ : await SendWithFakeResponseFromRequestAsync(request, cancellationToken);
+
+ private HttpResponseMessage SendWithFakeResponseFromRequest(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ foreach (var func in options.FakeResponseFromRequests)
+ {
+ try
+ {
+ var response = func(request);
+ if (response is null)
+ continue;
+
+ LogDebug("Sync fake request found for client {ClientName}. Returning fake response...", clientName);
+ return response;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "An error occurred while trying to get a sync fake request for client {ClientName}.", clientName);
+ }
+ }
+
+ LogDebug("No sync fake request found for client {ClientName}. Forwarding request to the next handler...", clientName);
+ return SendWithFakeResponseFromResponse(request, cancellationToken);
+ }
+
+ private async Task SendWithFakeResponseFromRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ foreach (var func in options.FakeResponsesFromRequestsAsync)
+ {
+ try
+ {
+ var response = await func(request);
+ if (response is null)
+ continue;
+
+ LogDebug("Async fake request found for client {ClientName}. Returning fake response...", clientName);
+ return response;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "An error occurred while trying to get a async fake request for client {ClientName}.", clientName);
+ }
+ }
+
+ LogDebug("No async fake request found for client {ClientName}. Forwarding request to the next handler...", clientName);
+ return await SendWithFakeResponseFromResponseAsync(request, cancellationToken);
+ }
+
+ private HttpResponseMessage SendWithFakeResponseFromResponse(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var response = base.Send(request, cancellationToken);
+
+ foreach (var func in options.FakeResponseFromResponses)
+ {
+ try
+ {
+ var newResponse = func(response);
+ if (newResponse is null)
+ continue;
+
+ LogDebug("Sync fake response found for client {ClientName}. Returning fake response...", clientName);
+ return newResponse;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "An error occurred while trying to get a sync fake response for client {ClientName}.", clientName);
+ }
+ }
+
+ LogDebug("No sync fake response found for client {ClientName}. Returning original response...", clientName);
+ return response;
+ }
+
+ private async Task SendWithFakeResponseFromResponseAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var response = await base.SendAsync(request, cancellationToken);
+
+ foreach (var func in options.FakeResponseFromResponsesAsync)
+ {
+ try
+ {
+ var newResponse = await func(response);
+ if (newResponse is null)
+ continue;
+
+ LogDebug("Async fake response found for client {ClientName}. Returning fake response...", clientName);
+ return newResponse;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "An error occurred while trying to get a async fake response for client {ClientName}.", clientName);
+ }
+ }
+
+ LogDebug("No async fake response found for client {ClientName}. Returning original response...", clientName);
+ return response;
+ }
+
+ private bool UseFakeHandler()
+ {
+ var isEnabled = options.Enabled && !_isProduction;
+ if (!isEnabled)
+ LogDebug("Fake handler is disabled for client {ClientName}. Enabled: {Enabled} | Production: {Production}. Forwarding request to the next handler...", clientName, options.Enabled, _isProduction);
+
+ return isEnabled;
+ }
+
+ private void LogDebug(string message, params object?[] args)
+ {
+ if (!_logger.IsEnabled(LogLevel.Debug))
+ return;
+
+ _logger.LogDebug(message, args);
+ }
+}
diff --git a/src/FakeOptions.cs b/src/FakeOptions.cs
new file mode 100644
index 0000000..061edae
--- /dev/null
+++ b/src/FakeOptions.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Fresp;
+
+public class FakeOptions
+{
+ internal readonly List> FakeResponseFromResponses = [];
+ internal readonly List>> FakeResponseFromResponsesAsync = [];
+
+ internal readonly List> FakeResponseFromRequests = [];
+ internal readonly List>> FakeResponsesFromRequestsAsync = [];
+
+ ///
+ /// Enabled or disable the handler to return fake responses. Default is false.
+ ///
+ public bool Enabled { get; set; }
+
+ ///
+ /// The name of the client that will be used to match the . If not provided, the name from will be used.
+ ///
+ public string? ClientName { get; set; } = null;
+
+ ///
+ /// Add a fake sync response to the handler that match .
+ ///
+ /// A Func that takes an and returns an or null.
+ public void AddFakeResponseFromRequest(Func fake)
+ => FakeResponseFromRequests.Add(fake);
+
+ ///
+ /// Add a fake async response to the handler that match .
+ ///
+ /// A Func that takes an and returns an or null.
+ public void AddFakeResponseFromRequestAsync(Func> fake)
+ => FakeResponsesFromRequestsAsync.Add(fake);
+
+ ///
+ /// Add a fake sync response to the handler that match .
+ ///
+ /// The type of the fake response that implements .
+ public void AddFakeResponseFromRequest() where T : IFakeResponseFromRequest, new()
+ => FakeResponseFromRequests.Add(new T().GetFakeResponseFromRequest());
+
+ ///
+ /// Add a fake async response to the handler that match .
+ ///
+ /// The type of the fake response that implements .
+ public void AddFakeResponseFromRequestAsync() where T : IFakeResponseFromRequestAsync, new()
+ => FakeResponsesFromRequestsAsync.Add(new T().GetFakeResponseFromRequestAsync());
+
+ ///
+ /// Add a fake sync response to the handler that match .
+ ///
+ /// The type of the fake response that implements .
+ public void AddFakeResponseFromResponse() where T : IFakeResponseFromResponse, new()
+ => FakeResponseFromResponses.Add(new T().GetFakeResponseFromResponse());
+
+ ///
+ /// Add a fake async response to the handler that match .
+ ///
+ /// The type of the fake response that implements .
+ public void AddFakeResponseFromResponseAsync() where T : IFakeResponseFromResponseAsync, new()
+ => FakeResponseFromResponsesAsync.Add(new T().GetFakeResponseFromResponseAsync());
+
+ ///
+ /// Add a fake sync response to the handler that match .
+ ///
+ /// A Func that takes an and returns an or null.
+ public void AddFakeResponseFromResponse(Func fake)
+ => FakeResponseFromResponses.Add(fake);
+
+ ///
+ /// Add a fake async response to the handler that match .
+ ///
+ /// A Func that takes an and returns an or null.
+ public void AddFakeResponseFromResponseAsync(Func> fake)
+ => FakeResponseFromResponsesAsync.Add(fake);
+}
diff --git a/src/FakeResponseHandler.cs b/src/FakeResponseHandler.cs
deleted file mode 100644
index 1451f67..0000000
--- a/src/FakeResponseHandler.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-
-namespace Fresp;
-
-internal class FakeResponseHandler(FakeResponseOptions options, string clientName, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory) : DelegatingHandler
-{
- private readonly ILogger _logger = loggerFactory.CreateLogger(nameof(FakeResponseHandler));
- private readonly bool _isProduction = hostEnvironment.IsProduction();
-
- protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- if (!UseFakeResponse())
- return base.Send(request, cancellationToken);
-
- foreach (var func in options.Fakes)
- {
- try
- {
- var response = func(request);
- if (response is null)
- continue;
-
- LogDebug("Sync fake response found for client {ClientName}. Returning fake response...", clientName);
- return response;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "An error occurred while trying to get a sync fake response for client {ClientName}.", clientName);
- }
- }
-
- LogDebug("No sync fake response found for client {ClientName}. Forwarding request to the next handler...", clientName);
- return base.Send(request, cancellationToken);
- }
-
- protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- if (!UseFakeResponse())
- return await base.SendAsync(request, cancellationToken);
-
- foreach (var func in options.FakesAsync)
- {
- try
- {
- var response = await func(request);
- if (response is null)
- continue;
-
- LogDebug("Async fake response found for client {ClientName}. Returning fake response...", clientName);
- return response;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "An error occurred while trying to get a async fake response for client {ClientName}.", clientName);
- }
- }
-
- LogDebug("No async fake response found for client {ClientName}. Forwarding request to the next handler...", clientName);
- return await base.SendAsync(request, cancellationToken);
- }
-
- private bool UseFakeResponse()
- {
- var isEnabled = options.Enabled && !_isProduction;
- if (!isEnabled)
- LogDebug("Fake response is disabled for client {ClientName}. Enabled: {Enabled} | Production: {Production}. Forwarding request to the next handler...", clientName, options.Enabled, _isProduction);
-
- return isEnabled;
- }
-
- private void LogDebug(string message, params object?[] args)
- {
- if (!_logger.IsEnabled(LogLevel.Debug))
- return;
-
- _logger.LogDebug(message, args);
- }
-}
diff --git a/src/FakeResponseOptions.cs b/src/FakeResponseOptions.cs
deleted file mode 100644
index 79aac35..0000000
--- a/src/FakeResponseOptions.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Threading.Tasks;
-
-namespace Fresp;
-
-public class FakeResponseOptions
-{
- internal readonly List> Fakes = [];
- internal readonly List>> FakesAsync = [];
-
- ///
- /// Enabled or disable the handler to return fake responses. Default is false.
- ///
- public bool Enabled { get; set; }
-
- ///
- /// The name of the client that will be used to match the . If null, the name from will be used.
- ///
- public string? ClientName { get; set; } = null;
-
- ///
- /// Add a fake sync response to the handler that match .
- ///
- /// A Func that takes an and returns an or null.
- public void AddFakeResponse(Func fake) => Fakes.Add(fake);
-
- ///
- /// Add a fake async response to the handler that match .
- ///
- /// A Func that takes an and returns an or null.
- public void AddFakeResponseAsync(Func> fake) => FakesAsync.Add(fake);
-}
diff --git a/src/Fresp.csproj b/src/Fresp.csproj
index d34cf1c..85f923e 100644
--- a/src/Fresp.csproj
+++ b/src/Fresp.csproj
@@ -5,7 +5,7 @@
13
disable
enable
- 1.0.0
+ 2.0.0
Fresp
Fresp
Fresp is a .NET NuGet package designed to provide fake responses for external APIs, aiding in testing environments such as DEV, UAT, HML, and QA.
diff --git a/src/HttpClientBuilderExtensions.cs b/src/HttpClientBuilderExtensions.cs
index 1c3a450..719e89a 100644
--- a/src/HttpClientBuilderExtensions.cs
+++ b/src/HttpClientBuilderExtensions.cs
@@ -5,22 +5,19 @@
namespace Fresp;
-///
-/// Provides extension methods for to add a .
-///
public static class HttpClientBuilderExtensions
{
///
- /// Adds a to the .
+ /// Adds a to the .
///
/// The to add the handler to.
- /// An optional to configure the .
- /// The with the added.
- public static IHttpClientBuilder AddFakeResponseHandler(this IHttpClientBuilder builder, Action? options = null)
+ /// An optional to configure the .
+ /// The with the added.
+ public static IHttpClientBuilder AddFakeHandler(this IHttpClientBuilder builder, Action? options = null)
{
- var handlerOptions = new FakeResponseOptions();
+ var handlerOptions = new FakeOptions();
options?.Invoke(handlerOptions);
- builder.AddHttpMessageHandler(services => new FakeResponseHandler(handlerOptions, handlerOptions.ClientName ?? builder.Name, services.GetRequiredService(), services.GetRequiredService()));
+ builder.AddHttpMessageHandler(services => new FakeHandler(handlerOptions, handlerOptions.ClientName ?? builder.Name, services.GetRequiredService(), services.GetRequiredService()));
return builder;
}
diff --git a/src/IFake.cs b/src/IFake.cs
new file mode 100644
index 0000000..ce629da
--- /dev/null
+++ b/src/IFake.cs
@@ -0,0 +1,25 @@
+using System.Net.Http;
+using System;
+using System.Threading.Tasks;
+
+namespace Fresp;
+
+public interface IFakeResponseFromRequest
+{
+ Func GetFakeResponseFromRequest();
+}
+
+public interface IFakeResponseFromRequestAsync
+{
+ Func> GetFakeResponseFromRequestAsync();
+}
+
+public interface IFakeResponseFromResponse
+{
+ Func GetFakeResponseFromResponse();
+}
+
+public interface IFakeResponseFromResponseAsync
+{
+ Func> GetFakeResponseFromResponseAsync();
+}
diff --git a/tests/Fresp.Tests/FakeResponseHandlerTests.cs b/tests/Fresp.Tests/FakeHandlerTests.cs
similarity index 56%
rename from tests/Fresp.Tests/FakeResponseHandlerTests.cs
rename to tests/Fresp.Tests/FakeHandlerTests.cs
index f3eb3fb..9b37506 100644
--- a/tests/Fresp.Tests/FakeResponseHandlerTests.cs
+++ b/tests/Fresp.Tests/FakeHandlerTests.cs
@@ -1,21 +1,22 @@
-using Microsoft.Extensions.Hosting;
+using Fresp.Tests.Mocks;
+using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Net;
namespace Fresp.Tests;
-public class FakeResponseHandlerTests
+public class FakeHandlerTests
{
[Fact]
public async Task Send_InProduction_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions();
+ var options = new FakeOptions();
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Production);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -35,7 +36,7 @@ public async Task Send_InProduction_ShouldForwardRequest()
public async Task Send_WithDisabled_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = false
};
@@ -43,7 +44,7 @@ public async Task Send_WithDisabled_ShouldForwardRequest()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -63,12 +64,12 @@ public async Task Send_WithDisabled_ShouldForwardRequest()
public async Task SendAsync_InProduction_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions();
+ var options = new FakeOptions();
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Production);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -88,7 +89,7 @@ public async Task SendAsync_InProduction_ShouldForwardRequest()
public async Task SendAsync_WithDisabled_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = false
};
@@ -96,7 +97,7 @@ public async Task SendAsync_WithDisabled_ShouldForwardRequest()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -116,12 +117,12 @@ public async Task SendAsync_WithDisabled_ShouldForwardRequest()
public async Task Send_WithoutFakes_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions { Enabled = true };
+ var options = new FakeOptions { Enabled = true };
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -137,14 +138,15 @@ public async Task Send_WithoutFakes_ShouldForwardRequest()
}
[Fact]
- public async Task Send_WithFakes_ShouldReturnFromFake()
+ public async Task Send_WithFakeResponseFromRequest_ShouldReturnFromFake()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
- Enabled = true
+ Enabled = true,
+ ClientName = "otherName"
};
- options.AddFakeResponse(request =>
+ options.AddFakeResponseFromRequest(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post)
{
@@ -158,7 +160,7 @@ public async Task Send_WithFakes_ShouldReturnFromFake()
return null;
});
- options.AddFakeResponse(request =>
+ options.AddFakeResponseFromRequest(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake-2") && request.Method == HttpMethod.Get)
{
@@ -176,7 +178,7 @@ public async Task Send_WithFakes_ShouldReturnFromFake()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -202,14 +204,59 @@ public async Task Send_WithFakes_ShouldReturnFromFake()
}
[Fact]
- public async Task Send_WithFakes_ShouldReturnForward()
+ public async Task Send_WithFakeResponseFromResponse_ShouldReturnFromFake()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = true
};
- options.AddFakeResponse(request =>
+ options.AddFakeResponseFromResponse(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ return new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ };
+ }
+
+ return null;
+ });
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.IsEnabled(LogLevel.Debug).Returns(true);
+ var loggerFactory = Substitute.For();
+ loggerFactory.CreateLogger(Arg.Any()).Returns(logger);
+ var handler = new SutFakeHandler(options, "clienttest", environment, loggerFactory)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+ var request = new HttpRequestMessage(HttpMethod.Post, "/must-fake");
+
+ // Act
+ var response = handler.Send(request, CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ response.ReasonPhrase.Should().Be("Faked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Faked!");
+ }
+
+ [Fact]
+ public async Task Send_WithFakeResponseFromRequest_ShouldReturnForward()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromRequest(request =>
{
if (request.RequestUri?.AbsolutePath == "/must-fake" && request.Method == HttpMethod.Post)
{
@@ -223,7 +270,7 @@ public async Task Send_WithFakes_ShouldReturnForward()
return null;
});
- options.AddFakeResponse(request =>
+ options.AddFakeResponseFromRequest(request =>
{
if (request.RequestUri?.AbsolutePath == "/must-fake-2" && request.Method == HttpMethod.Get)
{
@@ -241,7 +288,7 @@ public async Task Send_WithFakes_ShouldReturnForward()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -266,16 +313,81 @@ public async Task Send_WithFakes_ShouldReturnForward()
content.Should().Be("Mocked!");
}
+ [Fact]
+ public async Task Send_WithFakeResponseFromResponse_ShouldReturnForward()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromResponse(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.InternalServerError)
+ {
+ return new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ };
+ }
+
+ return null;
+ });
+ options.AddFakeResponseFromResponse(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.GatewayTimeout)
+ {
+ return new HttpResponseMessage
+ {
+ Content = new StringContent("Faked2!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked2"
+ };
+ }
+
+ return null;
+ });
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+ var request = new HttpRequestMessage(HttpMethod.Post, "/must-not-fake");
+ var request2 = new HttpRequestMessage(HttpMethod.Get, "/must-not-fake-2");
+
+ // Act
+ var response = handler.Send(request, CancellationToken.None);
+ var response2 = handler.Send(request2, CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable);
+ response.ReasonPhrase.Should().Be("Mocked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Mocked!");
+
+ response2.Should().NotBeNull();
+ response2.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable);
+ response2.ReasonPhrase.Should().Be("Mocked");
+ content = await response2.Content.ReadAsStringAsync();
+ content.Should().Be("Mocked!");
+ }
+
[Fact]
public async Task SendAsync_WithoutFakes_ShouldForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions { Enabled = true };
+ var options = new FakeOptions { Enabled = true };
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -291,14 +403,14 @@ public async Task SendAsync_WithoutFakes_ShouldForwardRequest()
}
[Fact]
- public async Task SendAsync_WithFakes_ShouldReturnFromFake()
+ public async Task SendAsync_WithFakeResponseFromRequest_ShouldReturnFromFake()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = true
};
- options.AddFakeResponseAsync(request =>
+ options.AddFakeResponseFromRequestAsync(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post)
{
@@ -312,7 +424,7 @@ public async Task SendAsync_WithFakes_ShouldReturnFromFake()
return Task.FromResult(null);
});
- options.AddFakeResponseAsync(request =>
+ options.AddFakeResponseFromRequestAsync(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake-2") && request.Method == HttpMethod.Get)
{
@@ -330,7 +442,7 @@ public async Task SendAsync_WithFakes_ShouldReturnFromFake()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -356,14 +468,57 @@ public async Task SendAsync_WithFakes_ShouldReturnFromFake()
}
[Fact]
- public async Task SendAsync_WithFakes_ShouldReturnForward()
+ public async Task SendAsync_WithFakeResponseFromResponse_ShouldReturnFromFake()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromResponseAsync(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ return Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ });
+ }
+
+ return Task.FromResult(null);
+ });
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+ var request = new HttpRequestMessage(HttpMethod.Post, "/must-fake");
+
+ // Act
+ var response = await handler.SendAsync(request, CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ response.ReasonPhrase.Should().Be("Faked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Faked!");
+ }
+
+ [Fact]
+ public async Task SendAsync_WithFakeResponseFromRequest_ShouldReturnForward()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = true
};
- options.AddFakeResponseAsync(request =>
+ options.AddFakeResponseFromRequestAsync(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post)
{
@@ -377,7 +532,7 @@ public async Task SendAsync_WithFakes_ShouldReturnForward()
return Task.FromResult((HttpResponseMessage?)null);
});
- options.AddFakeResponseAsync(request =>
+ options.AddFakeResponseFromRequestAsync(request =>
{
if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake-2") && request.Method == HttpMethod.Get)
{
@@ -395,7 +550,7 @@ public async Task SendAsync_WithFakes_ShouldReturnForward()
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -421,19 +576,62 @@ public async Task SendAsync_WithFakes_ShouldReturnForward()
}
[Fact]
- public async Task Send_WithFakes_ShouldThrowsAndForwardRequest()
+ public async Task SendAsync_WithFakeResponseFromResponse_ShouldReturnForward()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = true
};
- options.AddFakeResponse(_ => throw new Exception("Fake exception"));
+ options.AddFakeResponseFromResponseAsync(response =>
+ {
+ if (response.StatusCode == HttpStatusCode.BadRequest)
+ {
+ return Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ });
+ }
+
+ return Task.FromResult((HttpResponseMessage?)null);
+ });
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+ var request = new HttpRequestMessage(HttpMethod.Post, "/must-not-fake");
+
+ // Act
+ var response = await handler.SendAsync(request, CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable);
+ response.ReasonPhrase.Should().Be("Mocked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Mocked!");
+ }
+
+ [Fact]
+ public async Task Send_WithFakeResponseFromRequest_ShouldThrowsAndForwardRequest()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromRequest(_ => throw new Exception("Fake exception"));
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -450,19 +648,48 @@ public async Task Send_WithFakes_ShouldThrowsAndForwardRequest()
}
[Fact]
- public async Task SendAsync_WithFakes_ShouldThrowsAndForwardRequest()
+ public async Task Send_WithFakeResponseFromResponse_ShouldThrowsAndForwardResponse()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromResponse(_ => throw new Exception("Fake exception"));
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+
+ // Act
+ var response = handler.Send(new HttpRequestMessage(), CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable);
+ response.ReasonPhrase.Should().Be("Mocked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Mocked!");
+ }
+
+ [Fact]
+ public async Task SendAsync_WithFakeResponseFromRequest_ShouldThrowsAndForwardRequest()
{
// Arrange
- var options = new FakeResponseOptions
+ var options = new FakeOptions
{
Enabled = true
};
- options.AddFakeResponseAsync(_ => throw new Exception("Fake exception"));
+ options.AddFakeResponseFromRequestAsync(_ => throw new Exception("Fake exception"));
var environment = Substitute.For();
environment.EnvironmentName.Returns(Environments.Development);
var logger = Substitute.For();
logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
- var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger)
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
{
InnerHandler = new MockDelegatingHandler()
};
@@ -477,4 +704,33 @@ public async Task SendAsync_WithFakes_ShouldThrowsAndForwardRequest()
var content = await response.Content.ReadAsStringAsync();
content.Should().Be("Mocked!");
}
+
+ [Fact]
+ public async Task SendAsync_WithFakeResponseFromResponse_ShouldThrowsAndForwardResponse()
+ {
+ // Arrange
+ var options = new FakeOptions
+ {
+ Enabled = true
+ };
+ options.AddFakeResponseFromResponseAsync(_ => throw new Exception("Fake exception"));
+ var environment = Substitute.For();
+ environment.EnvironmentName.Returns(Environments.Development);
+ var logger = Substitute.For();
+ logger.CreateLogger(Arg.Any()).Returns(Substitute.For());
+ var handler = new SutFakeHandler(options, "clienttest", environment, logger)
+ {
+ InnerHandler = new MockResponseDelegatingHandler()
+ };
+
+ // Act
+ var response = await handler.SendAsync(new HttpRequestMessage(), CancellationToken.None);
+
+ // Assert
+ response.Should().NotBeNull();
+ response.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable);
+ response.ReasonPhrase.Should().Be("Mocked");
+ var content = await response.Content.ReadAsStringAsync();
+ content.Should().Be("Mocked!");
+ }
}
diff --git a/tests/Fresp.Tests/Fresp.Tests.csproj b/tests/Fresp.Tests/Fresp.Tests.csproj
index 5ca2555..b735e45 100644
--- a/tests/Fresp.Tests/Fresp.Tests.csproj
+++ b/tests/Fresp.Tests/Fresp.Tests.csproj
@@ -23,8 +23,8 @@
-
-
+
+
diff --git a/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs b/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs
index 5763f93..fa0c624 100644
--- a/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs
+++ b/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs
@@ -1,4 +1,5 @@
-using Microsoft.Extensions.DependencyInjection;
+using Fresp.Tests.Mocks;
+using Microsoft.Extensions.DependencyInjection;
namespace Fresp.Tests;
@@ -12,7 +13,7 @@ public void AddFakeResponseHandler_WithoutOptions_ShouldAddSuccessfully()
builder.Name.Returns("TestClient");
// Act
- var act = () => builder.AddFakeResponseHandler();
+ var act = () => builder.AddFakeHandler();
// Assert
act.Should().NotThrow();
@@ -25,17 +26,23 @@ public void AddFakeResponseHandler_WithOptions_ShouldAddSuccessfully()
var builder = Substitute.For();
var optionsInvoked = false;
- Action configureOptions = options =>
+ Action configureOptions = options =>
{
optionsInvoked = true;
options.ClientName = "TestClient";
options.Enabled = true;
- options.AddFakeResponse(_ => new HttpResponseMessage());
- options.AddFakeResponseAsync(_ => Task.FromResult(new HttpResponseMessage()));
+ options.AddFakeResponseFromRequest(_ => new HttpResponseMessage());
+ options.AddFakeResponseFromRequestAsync(_ => Task.FromResult(new HttpResponseMessage()));
+ options.AddFakeResponseFromResponse(_ => new HttpResponseMessage());
+ options.AddFakeResponseFromResponseAsync(_ => Task.FromResult(new HttpResponseMessage()));
+ options.AddFakeResponseFromRequest();
+ options.AddFakeResponseFromRequestAsync();
+ options.AddFakeResponseFromResponse();
+ options.AddFakeResponseFromResponseAsync();
};
// Act
- var act = () => builder.AddFakeResponseHandler(configureOptions);
+ var act = () => builder.AddFakeHandler(configureOptions);
// Assert
act.Should().NotThrow();
diff --git a/tests/Fresp.Tests/MockDelegatingHandler.cs b/tests/Fresp.Tests/MockDelegatingHandler.cs
deleted file mode 100644
index 6d92439..0000000
--- a/tests/Fresp.Tests/MockDelegatingHandler.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Fresp.Tests;
-
-internal class MockDelegatingHandler : DelegatingHandler
-{
- protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => new HttpResponseMessage
- {
- Content = new StringContent("Mocked!"),
- StatusCode = System.Net.HttpStatusCode.Accepted,
- ReasonPhrase = "Mocked"
- };
-
- protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => Task.FromResult(new HttpResponseMessage
- {
- Content = new StringContent("Mocked!"),
- StatusCode = System.Net.HttpStatusCode.Accepted,
- ReasonPhrase = "Mocked"
- });
-}
diff --git a/tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs b/tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs
new file mode 100644
index 0000000..3d92fdf
--- /dev/null
+++ b/tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs
@@ -0,0 +1,35 @@
+namespace Fresp.Tests.Mocks;
+
+internal class MockDelegatingHandler : DelegatingHandler
+{
+ protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => new HttpResponseMessage
+ {
+ Content = new StringContent("Mocked!"),
+ StatusCode = System.Net.HttpStatusCode.Accepted,
+ ReasonPhrase = "Mocked"
+ };
+
+ protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Mocked!"),
+ StatusCode = System.Net.HttpStatusCode.Accepted,
+ ReasonPhrase = "Mocked"
+ });
+}
+
+internal class MockResponseDelegatingHandler : DelegatingHandler
+{
+ protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => new HttpResponseMessage
+ {
+ Content = new StringContent("Mocked!"),
+ StatusCode = System.Net.HttpStatusCode.ServiceUnavailable,
+ ReasonPhrase = "Mocked"
+ };
+
+ protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) => Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Mocked!"),
+ StatusCode = System.Net.HttpStatusCode.ServiceUnavailable,
+ ReasonPhrase = "Mocked"
+ });
+}
diff --git a/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs
new file mode 100644
index 0000000..9779d65
--- /dev/null
+++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs
@@ -0,0 +1,24 @@
+using System.Net;
+
+namespace Fresp.Tests.Mocks;
+
+internal class MockFakeResponseFromRequest : IFakeResponseFromRequest
+{
+ public Func GetFakeResponseFromRequest()
+ {
+ return request =>
+ {
+ if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post)
+ {
+ return new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ };
+ }
+
+ return null;
+ };
+ }
+}
diff --git a/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs
new file mode 100644
index 0000000..b4e989a
--- /dev/null
+++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs
@@ -0,0 +1,24 @@
+using System.Net;
+
+namespace Fresp.Tests.Mocks;
+
+internal class MockFakeResponseFromRequestAsync : IFakeResponseFromRequestAsync
+{
+ public Func> GetFakeResponseFromRequestAsync()
+ {
+ return async request =>
+ {
+ if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake-2") && request.Method == HttpMethod.Get)
+ {
+ return await Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ });
+ }
+
+ return await Task.FromResult((HttpResponseMessage?)null);
+ };
+ }
+}
diff --git a/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs
new file mode 100644
index 0000000..fa3b9be
--- /dev/null
+++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs
@@ -0,0 +1,24 @@
+using System.Net;
+
+namespace Fresp.Tests.Mocks;
+
+internal class MockFakeResponseFromResponse : IFakeResponseFromResponse
+{
+ public Func GetFakeResponseFromResponse()
+ {
+ return response =>
+ {
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ return new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ };
+ }
+
+ return null;
+ };
+ }
+}
\ No newline at end of file
diff --git a/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs
new file mode 100644
index 0000000..1b952a6
--- /dev/null
+++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs
@@ -0,0 +1,24 @@
+using System.Net;
+
+namespace Fresp.Tests.Mocks;
+
+internal class MockFakeResponseFromResponseAsync : IFakeResponseFromResponseAsync
+{
+ public Func> GetFakeResponseFromResponseAsync()
+ {
+ return async response =>
+ {
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ return await Task.FromResult(new HttpResponseMessage
+ {
+ Content = new StringContent("Faked!"),
+ StatusCode = HttpStatusCode.OK,
+ ReasonPhrase = "Faked"
+ });
+ }
+
+ return await Task.FromResult((HttpResponseMessage?)null);
+ };
+ }
+}
diff --git a/tests/Fresp.Tests/SutFakeResponseHandler.cs b/tests/Fresp.Tests/SutFakeHandler.cs
similarity index 64%
rename from tests/Fresp.Tests/SutFakeResponseHandler.cs
rename to tests/Fresp.Tests/SutFakeHandler.cs
index 945e2d9..22627dd 100644
--- a/tests/Fresp.Tests/SutFakeResponseHandler.cs
+++ b/tests/Fresp.Tests/SutFakeHandler.cs
@@ -3,7 +3,7 @@
namespace Fresp.Tests;
-internal class SutFakeResponseHandler(FakeResponseOptions options, string clientName, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory) : FakeResponseHandler(options, clientName, hostEnvironment, loggerFactory)
+internal class SutFakeHandler(FakeOptions options, string clientName, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory) : FakeHandler(options, clientName, hostEnvironment, loggerFactory)
{
public new HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) => base.Send(request, cancellationToken);