WithCallback-Async (#531)

This commit is contained in:
Stef Heyenrath
2020-11-04 16:32:32 +00:00
committed by GitHub
parent 5b083d753e
commit b8cbeb55b9
5 changed files with 147 additions and 51 deletions

View File

@@ -12,6 +12,7 @@ using WireMock.ResponseBuilders;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Util; using WireMock.Util;
using System.Threading.Tasks;
namespace WireMock.Net.ConsoleApplication namespace WireMock.Net.ConsoleApplication
{ {
@@ -521,9 +522,29 @@ namespace WireMock.Net.ConsoleApplication
.WithBodyAsJson(new { Id = "5bdf076c-5654-4b3e-842c-7caf1fabf8c9" })); .WithBodyAsJson(new { Id = "5bdf076c-5654-4b3e-842c-7caf1fabf8c9" }));
server server
.Given(Request.Create().WithPath("/random200or505").UsingGet()) .Given(Request.Create().WithPath("/random200or505").UsingGet())
.RespondWith(Response.Create().WithCallback(request => new ResponseMessage .RespondWith(Response.Create().WithCallback(request =>
{ {
StatusCode = new Random().Next(1, 100) == 1 ? 504 : 200 int code = new Random().Next(1, 2) == 1 ? 505 : 200;
return new ResponseMessage
{
BodyData = new BodyData { BodyAsString = "random200or505:" + code, DetectedBodyType = Types.BodyType.String },
StatusCode = code
};
}));
server
.Given(Request.Create().WithPath("/random200or505async").UsingGet())
.RespondWith(Response.Create().WithCallback(async request =>
{
await Task.Delay(1);
int code = new Random().Next(1, 2) == 1 ? 505 : 200;
return new ResponseMessage
{
BodyData = new BodyData { BodyAsString = "random200or505async:" + code, DetectedBodyType = Types.BodyType.String },
StatusCode = code
};
})); }));
System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented)); System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented));

View File

@@ -1,19 +1,27 @@
using System; using System;
using JetBrains.Annotations; using System.Threading.Tasks;
using WireMock.ResponseProviders; using JetBrains.Annotations;
using WireMock.ResponseProviders;
namespace WireMock.ResponseBuilders
{ namespace WireMock.ResponseBuilders
/// <summary> {
/// The CallbackResponseBuilder interface. /// <summary>
/// </summary> /// The CallbackResponseBuilder interface.
public interface ICallbackResponseBuilder : IResponseProvider /// </summary>
{ public interface ICallbackResponseBuilder : IResponseProvider
/// <summary> {
/// The callback builder /// <summary>
/// </summary> /// The callback builder
/// <returns>The <see cref="IResponseBuilder"/>.</returns> /// </summary>
[PublicAPI] /// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler); [PublicAPI]
} IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler);
/// <summary>
/// The async callback builder
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, Task<ResponseMessage>> callbackHandler);
}
} }

View File

@@ -0,0 +1,60 @@
using System;
using System.Threading.Tasks;
using WireMock.Validation;
namespace WireMock.ResponseBuilders
{
public partial class Response
{
/// <summary>
/// A delegate to execute to generate the response.
/// </summary>
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
/// <summary>
/// A delegate to execute to generate the response async.
/// </summary>
public Func<RequestMessage, Task<ResponseMessage>> CallbackAsync { get; private set; }
/// <summary>
/// Defines if the method WithCallback(...) is used.
/// </summary>
public bool WithCallbackUsed { get; private set; }
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, ResponseMessage})"/>
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, Task{ResponseMessage}})"/>
public IResponseBuilder WithCallback(Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
Callback = callbackHandler;
return this;
}
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
CallbackAsync = callbackHandler;
return this;
}
}
}

View File

@@ -42,16 +42,6 @@ namespace WireMock.ResponseBuilders
/// </summary> /// </summary>
public ResponseMessage ResponseMessage { get; } public ResponseMessage ResponseMessage { get; }
/// <summary>
/// A delegate to execute to generate the response.
/// </summary>
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
/// <summary>
/// Defines if the method WithCallback(...) is used.
/// </summary>
public bool WithCallbackUsed { get; private set; }
/// <summary> /// <summary>
/// Creates this instance. /// Creates this instance.
/// </summary> /// </summary>
@@ -311,25 +301,6 @@ namespace WireMock.ResponseBuilders
return WithDelay(TimeSpan.FromMilliseconds(milliseconds)); return WithDelay(TimeSpan.FromMilliseconds(milliseconds));
} }
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
Callback = callbackHandler;
return this;
}
/// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, IWireMockServerSettings)"/> /// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, IWireMockServerSettings)"/>
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings) public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
{ {
@@ -365,13 +336,20 @@ namespace WireMock.ResponseBuilders
} }
ResponseMessage responseMessage; ResponseMessage responseMessage;
if (Callback == null) if (Callback == null && CallbackAsync == null)
{ {
responseMessage = ResponseMessage; responseMessage = ResponseMessage;
} }
else else
{ {
responseMessage = Callback(requestMessage); if (Callback != null)
{
responseMessage = Callback(requestMessage);
}
else
{
responseMessage = await CallbackAsync(requestMessage);
}
if (!WithCallbackUsed) if (!WithCallbackUsed)
{ {

View File

@@ -13,6 +13,35 @@ namespace WireMock.Net.Tests.ResponseBuilders
{ {
private readonly WireMockServerSettings _settings = new WireMockServerSettings(); private readonly WireMockServerSettings _settings = new WireMockServerSettings();
[Fact]
public async Task Response_WithCallbackAsync()
{
// Assign
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
var response = Response.Create()
.WithCallback(async request =>
{
await Task.Delay(1);
return new ResponseMessage
{
BodyData = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = request.Path + "Bar"
},
StatusCode = 302
};
});
// Act
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
// Assert
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
responseMessage.StatusCode.Should().Be(302);
}
[Fact] [Fact]
public async Task Response_WithCallback() public async Task Response_WithCallback()
{ {