From 267dafd698fb8ba8cab2500d6576366d93db3d59 Mon Sep 17 00:00:00 2001 From: Luiz Adolfo Date: Fri, 14 Feb 2025 19:39:08 -0300 Subject: [PATCH 1/2] Bump version to 2.0.0 and refactor fake response handling with new interfaces and tests --- README.md | 127 +++++++- src/FakeHandler.cs | 137 ++++++++ src/FakeOptions.cs | 82 +++++ src/FakeResponseHandler.cs | 83 ----- src/FakeResponseOptions.cs | 34 -- src/Fresp.csproj | 2 +- src/HttpClientBuilderExtensions.cs | 15 +- src/IFake.cs | 25 ++ tests/Fresp.Tests/FakeResponseHandlerTests.cs | 308 ++++++++++++++++-- .../HttpClientBuilderExtensionsTests.cs | 16 +- tests/Fresp.Tests/MockDelegatingHandler.cs | 17 + .../MockFakeResponseFromRequest.cs | 25 ++ .../MockFakeResponseFromRequestAsync.cs | 25 ++ .../MockFakeResponseFromResponse.cs | 24 ++ .../MockFakeResponseFromResponseAsync.cs | 24 ++ tests/Fresp.Tests/SutFakeResponseHandler.cs | 2 +- 16 files changed, 773 insertions(+), 173 deletions(-) create mode 100644 src/FakeHandler.cs create mode 100644 src/FakeOptions.cs delete mode 100644 src/FakeResponseHandler.cs delete mode 100644 src/FakeResponseOptions.cs create mode 100644 src/IFake.cs create mode 100644 tests/Fresp.Tests/MockFakeResponseFromRequest.cs create mode 100644 tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs create mode 100644 tests/Fresp.Tests/MockFakeResponseFromResponse.cs create mode 100644 tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs diff --git a/README.md b/README.md index aaf5c8b..3953dcc 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [![Coverage Status](https://coveralls.io/repos/github/Adolfok3/Fresp/badge.svg?branch=main)](https://coveralls.io/github/Adolfok3/Fresp?branch=main) [![NuGet Version](https://img.shields.io/nuget/vpre/fresp)](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/FakeResponseHandlerTests.cs index f3eb3fb..d6b1964 100644 --- a/tests/Fresp.Tests/FakeResponseHandlerTests.cs +++ b/tests/Fresp.Tests/FakeResponseHandlerTests.cs @@ -10,7 +10,7 @@ public class FakeResponseHandlerTests 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(); @@ -35,7 +35,7 @@ public async Task Send_InProduction_ShouldForwardRequest() public async Task Send_WithDisabled_ShouldForwardRequest() { // Arrange - var options = new FakeResponseOptions + var options = new FakeOptions { Enabled = false }; @@ -63,7 +63,7 @@ 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(); @@ -88,7 +88,7 @@ public async Task SendAsync_InProduction_ShouldForwardRequest() public async Task SendAsync_WithDisabled_ShouldForwardRequest() { // Arrange - var options = new FakeResponseOptions + var options = new FakeOptions { Enabled = false }; @@ -116,7 +116,7 @@ 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(); @@ -137,14 +137,14 @@ 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 }; - options.AddFakeResponse(request => + options.AddFakeResponseFromRequest(request => { if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post) { @@ -158,7 +158,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) { @@ -202,14 +202,57 @@ 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.CreateLogger(Arg.Any()).Returns(Substitute.For()); + var handler = new SutFakeResponseHandler(options, "clienttest", environment, logger) + { + 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 +266,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) { @@ -266,11 +309,76 @@ 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 SutFakeResponseHandler(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(); @@ -291,14 +399,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 +420,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) { @@ -356,14 +464,57 @@ public async Task SendAsync_WithFakes_ShouldReturnFromFake() } [Fact] - public async Task SendAsync_WithFakes_ShouldReturnForward() + public async Task SendAsync_WithFakeResponseFromResponse_ShouldReturnFromFake() { // Arrange - var options = new FakeResponseOptions + var options = new FakeOptions { Enabled = true }; - options.AddFakeResponseAsync(request => + 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 SutFakeResponseHandler(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 FakeOptions + { + Enabled = true + }; + options.AddFakeResponseFromRequestAsync(request => { if (request.RequestUri != null && request.RequestUri.ToString().EndsWith("/must-fake") && request.Method == HttpMethod.Post) { @@ -377,7 +528,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) { @@ -421,14 +572,57 @@ public async Task SendAsync_WithFakes_ShouldReturnForward() } [Fact] - public async Task Send_WithFakes_ShouldThrowsAndForwardRequest() + public async Task SendAsync_WithFakeResponseFromResponse_ShouldReturnForward() + { + // Arrange + var options = new FakeOptions + { + Enabled = true + }; + 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) + { + 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 FakeResponseOptions + var options = new FakeOptions { Enabled = true }; - options.AddFakeResponse(_ => throw new Exception("Fake exception")); + options.AddFakeResponseFromRequest(_ => throw new Exception("Fake exception")); var environment = Substitute.For(); environment.EnvironmentName.Returns(Environments.Development); var logger = Substitute.For(); @@ -450,14 +644,43 @@ 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 SutFakeResponseHandler(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(); @@ -477,4 +700,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 SutFakeResponseHandler(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/HttpClientBuilderExtensionsTests.cs b/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs index 5763f93..70d6b53 100644 --- a/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs +++ b/tests/Fresp.Tests/HttpClientBuilderExtensionsTests.cs @@ -12,7 +12,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 +25,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 index 6d92439..7a9f7fc 100644 --- a/tests/Fresp.Tests/MockDelegatingHandler.cs +++ b/tests/Fresp.Tests/MockDelegatingHandler.cs @@ -16,3 +16,20 @@ protected override Task SendAsync(HttpRequestMessage reques 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/MockFakeResponseFromRequest.cs b/tests/Fresp.Tests/MockFakeResponseFromRequest.cs new file mode 100644 index 0000000..4db1e4e --- /dev/null +++ b/tests/Fresp.Tests/MockFakeResponseFromRequest.cs @@ -0,0 +1,25 @@ + +using System.Net; + +namespace Fresp.Tests; + +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/MockFakeResponseFromRequestAsync.cs b/tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs new file mode 100644 index 0000000..cc05034 --- /dev/null +++ b/tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs @@ -0,0 +1,25 @@ + +using System.Net; + +namespace Fresp.Tests; + +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/MockFakeResponseFromResponse.cs b/tests/Fresp.Tests/MockFakeResponseFromResponse.cs new file mode 100644 index 0000000..0305c35 --- /dev/null +++ b/tests/Fresp.Tests/MockFakeResponseFromResponse.cs @@ -0,0 +1,24 @@ +using System.Net; + +namespace Fresp.Tests; + +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/MockFakeResponseFromResponseAsync.cs b/tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs new file mode 100644 index 0000000..dfa9574 --- /dev/null +++ b/tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs @@ -0,0 +1,24 @@ +using System.Net; + +namespace Fresp.Tests; + +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/SutFakeResponseHandler.cs index 945e2d9..b3e528a 100644 --- a/tests/Fresp.Tests/SutFakeResponseHandler.cs +++ b/tests/Fresp.Tests/SutFakeResponseHandler.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 SutFakeResponseHandler(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); From 165af1219ad8b94b090ffaa4dfc93d6608f09d37 Mon Sep 17 00:00:00 2001 From: Luiz Adolfo Date: Fri, 14 Feb 2025 19:47:35 -0300 Subject: [PATCH 2/2] Move mock to mock folder in test project --- ...nseHandlerTests.cs => FakeHandlerTests.cs} | 50 ++++++++++--------- tests/Fresp.Tests/Fresp.Tests.csproj | 4 +- .../HttpClientBuilderExtensionsTests.cs | 3 +- .../{ => Mocks}/MockDelegatingHandler.cs | 2 +- .../MockFakeResponseFromRequest.cs | 5 +- .../MockFakeResponseFromRequestAsync.cs | 5 +- .../MockFakeResponseFromResponse.cs | 2 +- .../MockFakeResponseFromResponseAsync.cs | 2 +- ...keResponseHandler.cs => SutFakeHandler.cs} | 2 +- 9 files changed, 39 insertions(+), 36 deletions(-) rename tests/Fresp.Tests/{FakeResponseHandlerTests.cs => FakeHandlerTests.cs} (93%) rename tests/Fresp.Tests/{ => Mocks}/MockDelegatingHandler.cs (97%) rename tests/Fresp.Tests/{ => Mocks}/MockFakeResponseFromRequest.cs (92%) rename tests/Fresp.Tests/{ => Mocks}/MockFakeResponseFromRequestAsync.cs (93%) rename tests/Fresp.Tests/{ => Mocks}/MockFakeResponseFromResponse.cs (95%) rename tests/Fresp.Tests/{ => Mocks}/MockFakeResponseFromResponseAsync.cs (96%) rename tests/Fresp.Tests/{SutFakeResponseHandler.cs => SutFakeHandler.cs} (66%) diff --git a/tests/Fresp.Tests/FakeResponseHandlerTests.cs b/tests/Fresp.Tests/FakeHandlerTests.cs similarity index 93% rename from tests/Fresp.Tests/FakeResponseHandlerTests.cs rename to tests/Fresp.Tests/FakeHandlerTests.cs index d6b1964..9b37506 100644 --- a/tests/Fresp.Tests/FakeResponseHandlerTests.cs +++ b/tests/Fresp.Tests/FakeHandlerTests.cs @@ -1,10 +1,11 @@ -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() @@ -15,7 +16,7 @@ public async Task Send_InProduction_ShouldForwardRequest() 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() }; @@ -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() }; @@ -68,7 +69,7 @@ public async Task SendAsync_InProduction_ShouldForwardRequest() 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() }; @@ -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() }; @@ -121,7 +122,7 @@ public async Task Send_WithoutFakes_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() }; @@ -142,7 +143,8 @@ public async Task Send_WithFakeResponseFromRequest_ShouldReturnFromFake() // Arrange var options = new FakeOptions { - Enabled = true + Enabled = true, + ClientName = "otherName" }; options.AddFakeResponseFromRequest(request => { @@ -176,7 +178,7 @@ public async Task Send_WithFakeResponseFromRequest_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() }; @@ -225,9 +227,11 @@ public async Task Send_WithFakeResponseFromResponse_ShouldReturnFromFake() }); 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 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() }; @@ -284,7 +288,7 @@ public async Task Send_WithFakeResponseFromRequest_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() }; @@ -349,7 +353,7 @@ public async Task Send_WithFakeResponseFromResponse_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 MockResponseDelegatingHandler() }; @@ -383,7 +387,7 @@ public async Task SendAsync_WithoutFakes_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() }; @@ -438,7 +442,7 @@ public async Task SendAsync_WithFakeResponseFromRequest_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() }; @@ -489,7 +493,7 @@ public async Task SendAsync_WithFakeResponseFromResponse_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 MockResponseDelegatingHandler() }; @@ -546,7 +550,7 @@ public async Task SendAsync_WithFakeResponseFromRequest_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() }; @@ -597,7 +601,7 @@ public async Task SendAsync_WithFakeResponseFromResponse_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 MockResponseDelegatingHandler() }; @@ -627,7 +631,7 @@ public async Task Send_WithFakeResponseFromRequest_ShouldThrowsAndForwardRequest 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() }; @@ -656,7 +660,7 @@ public async Task Send_WithFakeResponseFromResponse_ShouldThrowsAndForwardRespon 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() }; @@ -685,7 +689,7 @@ public async Task SendAsync_WithFakeResponseFromRequest_ShouldThrowsAndForwardRe 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() }; @@ -714,7 +718,7 @@ public async Task SendAsync_WithFakeResponseFromResponse_ShouldThrowsAndForwardR 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() }; 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 70d6b53..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; diff --git a/tests/Fresp.Tests/MockDelegatingHandler.cs b/tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs similarity index 97% rename from tests/Fresp.Tests/MockDelegatingHandler.cs rename to tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs index 7a9f7fc..3d92fdf 100644 --- a/tests/Fresp.Tests/MockDelegatingHandler.cs +++ b/tests/Fresp.Tests/Mocks/MockDelegatingHandler.cs @@ -1,4 +1,4 @@ -namespace Fresp.Tests; +namespace Fresp.Tests.Mocks; internal class MockDelegatingHandler : DelegatingHandler { diff --git a/tests/Fresp.Tests/MockFakeResponseFromRequest.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs similarity index 92% rename from tests/Fresp.Tests/MockFakeResponseFromRequest.cs rename to tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs index 4db1e4e..9779d65 100644 --- a/tests/Fresp.Tests/MockFakeResponseFromRequest.cs +++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequest.cs @@ -1,7 +1,6 @@ - -using System.Net; +using System.Net; -namespace Fresp.Tests; +namespace Fresp.Tests.Mocks; internal class MockFakeResponseFromRequest : IFakeResponseFromRequest { diff --git a/tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs similarity index 93% rename from tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs rename to tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs index cc05034..b4e989a 100644 --- a/tests/Fresp.Tests/MockFakeResponseFromRequestAsync.cs +++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromRequestAsync.cs @@ -1,7 +1,6 @@ - -using System.Net; +using System.Net; -namespace Fresp.Tests; +namespace Fresp.Tests.Mocks; internal class MockFakeResponseFromRequestAsync : IFakeResponseFromRequestAsync { diff --git a/tests/Fresp.Tests/MockFakeResponseFromResponse.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs similarity index 95% rename from tests/Fresp.Tests/MockFakeResponseFromResponse.cs rename to tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs index 0305c35..fa3b9be 100644 --- a/tests/Fresp.Tests/MockFakeResponseFromResponse.cs +++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponse.cs @@ -1,6 +1,6 @@ using System.Net; -namespace Fresp.Tests; +namespace Fresp.Tests.Mocks; internal class MockFakeResponseFromResponse : IFakeResponseFromResponse { diff --git a/tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs similarity index 96% rename from tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs rename to tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs index dfa9574..1b952a6 100644 --- a/tests/Fresp.Tests/MockFakeResponseFromResponseAsync.cs +++ b/tests/Fresp.Tests/Mocks/MockFakeResponseFromResponseAsync.cs @@ -1,6 +1,6 @@ using System.Net; -namespace Fresp.Tests; +namespace Fresp.Tests.Mocks; internal class MockFakeResponseFromResponseAsync : IFakeResponseFromResponseAsync { diff --git a/tests/Fresp.Tests/SutFakeResponseHandler.cs b/tests/Fresp.Tests/SutFakeHandler.cs similarity index 66% rename from tests/Fresp.Tests/SutFakeResponseHandler.cs rename to tests/Fresp.Tests/SutFakeHandler.cs index b3e528a..22627dd 100644 --- a/tests/Fresp.Tests/SutFakeResponseHandler.cs +++ b/tests/Fresp.Tests/SutFakeHandler.cs @@ -3,7 +3,7 @@ namespace Fresp.Tests; -internal class SutFakeResponseHandler(FakeOptions options, string clientName, IHostEnvironment hostEnvironment, ILoggerFactory loggerFactory) : FakeHandler(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);