Skip to content

Commit

Permalink
Improve test infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
romankr committed Sep 26, 2024
1 parent f507c8b commit 0551419
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Microsoft.Extensions.Logging;

namespace OddsCollector.Functions.Tests.Infrastructure.Logger;

internal static class LoggerFactory
{
public static ILogger<T> GetLoggerMock<T>() where T : class
{
return Substitute.For<ILogger<T>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Microsoft.Azure.Functions.Worker;

namespace OddsCollector.Functions.Tests.Infrastructure.ServiceBus;

internal static class ServiceBusMessageActionsFactory
{
public static ServiceBusMessageActions GetServiceBusMessageActionsMock()
{
return Substitute.For<ServiceBusMessageActions>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ namespace OddsCollector.Functions.Tests.Infrastructure.ServiceBus;

internal static class ServiceBusReceivedMessageFactory
{
public static ServiceBusReceivedMessage CreateFromObject(object obj)
public static IEnumerable<ServiceBusReceivedMessage> CreateFromObjects(IEnumerable<object> objects)
{
return objects.Select(CreateFromObject);
}

private static ServiceBusReceivedMessage CreateFromObject(object obj)
{
var serialized = Encoding.ASCII.GetBytes(JsonSerializer.Serialize(obj))
.Select(x => new ReadOnlyMemory<byte>([x]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using NSubstitute.ExceptionExtensions;
using OddsCollector.Functions.Models;
using OddsCollector.Functions.OddsApi;
using LoggerFactory = OddsCollector.Functions.Tests.Infrastructure.Logger.LoggerFactory;

namespace OddsCollector.Functions.Tests.Tests.Functions;

Expand All @@ -15,18 +16,16 @@ public async Task Run_WithValidParameters_ReturnsEventResults()
// Arrange
IEnumerable<EventResult> expectedEventResults = new List<EventResult> { new() };

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.EventResultsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.EventResultsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetEventResultsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(expectedEventResults));
var clientStub = GetOddsApiClientStub(expectedEventResults);

var function = new OddsCollector.Functions.Functions.EventResultsFunction(loggerMock, clientStub);

var token = new CancellationToken();
var cancellationToken = new CancellationToken();

// Act
var eventResults = await function.Run(token);
var eventResults = await function.Run(cancellationToken);

// Assert
eventResults.Should().NotBeNull().And.BeEquivalentTo(expectedEventResults);
Expand All @@ -40,18 +39,18 @@ public async Task Run_WithException_ReturnsEmptyEventResults()
// Arrange
var exception = new Exception();

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.EventResultsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.EventResultsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetEventResultsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.Throws(exception);

var function = new OddsCollector.Functions.Functions.EventResultsFunction(loggerMock, clientStub);

var token = new CancellationToken();
var cancellationToken = new CancellationToken();

// Act
var eventResults = await function.Run(token);
var eventResults = await function.Run(cancellationToken);

// Assert
eventResults.Should().NotBeNull().And.BeEmpty();
Expand All @@ -66,22 +65,30 @@ public async Task Run_WithValidParameters_ReturnsNoEventResults()
// Arrange
IEnumerable<EventResult> expectedEventResults = new List<EventResult>();

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.EventResultsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.EventResultsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetEventResultsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(expectedEventResults));
var clientStub = GetOddsApiClientStub(expectedEventResults);

var function = new OddsCollector.Functions.Functions.EventResultsFunction(loggerMock, clientStub);

var token = new CancellationToken();
var cancellationToken = new CancellationToken();

// Act
var eventResults = await function.Run(token);
var eventResults = await function.Run(cancellationToken);

// Assert
eventResults.Should().NotBeNull().And.BeEquivalentTo(expectedEventResults);

loggerMock.ReceivedWithAnyArgs().LogWarning(string.Empty, 1);
}

private static IOddsApiClient GetOddsApiClientStub(IEnumerable<EventResult> expectedEventResults)
{
var clientStub = Substitute.For<IOddsApiClient>();

clientStub.GetEventResultsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(expectedEventResults));

return clientStub;
}
}
40 changes: 21 additions & 19 deletions OddsCollector.Functions.Tests/Tests/Functions/PredictionFunction.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using NSubstitute.ReceivedExtensions;
using NSubstitute.ReceivedExtensions;
using OddsCollector.Functions.Models;
using OddsCollector.Functions.Strategies;
using OddsCollector.Functions.Tests.Infrastructure.CancellationToken;
using OddsCollector.Functions.Tests.Infrastructure.Data;
using OddsCollector.Functions.Tests.Infrastructure.Logger;
using OddsCollector.Functions.Tests.Infrastructure.ServiceBus;

namespace OddsCollector.Functions.Tests.Tests.Functions;
Expand All @@ -16,16 +14,18 @@ internal class PredictionFunction
public async Task Run_WithValidServiceBusMessage_ReturnsEventPrediction()
{
// Arrange
var loggerStub = Substitute.For<ILogger<OddsCollector.Functions.Functions.PredictionFunction>>();
var loggerStub = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.PredictionFunction>();

var upcomingEvent = new UpcomingEventBuilder().SetSampleData().Instance;

var expectedPrediction = new EventPredictionBuilder().SetSampleData().Instance;

ServiceBusReceivedMessage[] receivedMessages =
[ServiceBusReceivedMessageFactory.CreateFromObject(upcomingEvent)];
var receivedMessages =
ServiceBusReceivedMessageFactory.CreateFromObjects([
upcomingEvent
]).ToArray();

var actionsMock = Substitute.For<ServiceBusMessageActions>();
var actionsMock = ServiceBusMessageActionsFactory.GetServiceBusMessageActionsMock();

var strategyStub = Substitute.For<IPredictionStrategy>();
strategyStub.GetPrediction(Arg.Any<UpcomingEvent>(), Arg.Any<DateTime>()).Returns(expectedPrediction);
Expand All @@ -48,16 +48,18 @@ public async Task Run_WithValidServiceBusMessage_ReturnsEventPrediction()
public async Task Run_WithValidServiceBusMessageAndRequestedCancellation_ReturnsNoPredictions()
{
// Arrange
var loggerStub = Substitute.For<ILogger<OddsCollector.Functions.Functions.PredictionFunction>>();
var loggerStub = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.PredictionFunction>();

var upcomingEvent = new UpcomingEventBuilder().SetSampleData().Instance;

var expectedPrediction = new EventPredictionBuilder().SetSampleData().Instance;

ServiceBusReceivedMessage[] receivedMessages =
[ServiceBusReceivedMessageFactory.CreateFromObject(upcomingEvent)];
var receivedMessages =
ServiceBusReceivedMessageFactory.CreateFromObjects([
upcomingEvent
]).ToArray();

var actionsMock = Substitute.For<ServiceBusMessageActions>();
var actionsMock = ServiceBusMessageActionsFactory.GetServiceBusMessageActionsMock();

var strategyStub = Substitute.For<IPredictionStrategy>();
strategyStub.GetPrediction(Arg.Any<UpcomingEvent>(), Arg.Any<DateTime>()).Returns(expectedPrediction);
Expand All @@ -78,7 +80,7 @@ public async Task Run_WithValidServiceBusMessageAndRequestedCancellation_Returns
public async Task Run_WithInvalidItems_ReturnsSuccessfullyProcessedEventPredictions()
{
// Arrange
var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.PredictionFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.PredictionFunction>();

var goodUpcomingEvent = new UpcomingEventBuilder().SetSampleData().Instance;

Expand All @@ -87,13 +89,13 @@ public async Task Run_WithInvalidItems_ReturnsSuccessfullyProcessedEventPredicti

var expectedPrediction = new EventPredictionBuilder().SetSampleData().Instance;

ServiceBusReceivedMessage[] receivedMessages =
[
ServiceBusReceivedMessageFactory.CreateFromObject(badUpcomingEvent),
ServiceBusReceivedMessageFactory.CreateFromObject(goodUpcomingEvent)
];
var receivedMessages =
ServiceBusReceivedMessageFactory.CreateFromObjects([
badUpcomingEvent,
goodUpcomingEvent
]).ToArray();

var actionsMock = Substitute.For<ServiceBusMessageActions>();
var actionsMock = ServiceBusMessageActionsFactory.GetServiceBusMessageActionsMock();

var exception = new Exception();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
using System.Text.Json;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using OddsCollector.Functions.Models;
using OddsCollector.Functions.Tests.Infrastructure.Data;
using OddsCollector.Functions.Tests.Infrastructure.Logger;

namespace OddsCollector.Functions.Tests.Tests.Functions;

Expand All @@ -14,7 +14,7 @@ internal class PredictionsHttpFunction
public void Run_WithValidArguments_ReturnsValidResponse()
{
// Arrange
var loggerStub = Substitute.For<ILogger<OddsCollector.Functions.Functions.PredictionsHttpFunction>>();
var loggerStub = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.PredictionsHttpFunction>();

var function = new OddsCollector.Functions.Functions.PredictionsHttpFunction(loggerStub);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using NSubstitute.ExceptionExtensions;
using OddsCollector.Functions.Models;
using OddsCollector.Functions.OddsApi;
using LoggerFactory = OddsCollector.Functions.Tests.Infrastructure.Logger.LoggerFactory;

namespace OddsCollector.Functions.Tests.Tests.Functions;

Expand All @@ -15,7 +16,7 @@ public async Task Run_WithValidParameters_ReturnsEventResults()
// Arrange
IEnumerable<UpcomingEvent> expectedEventResults = new List<UpcomingEvent> { new() };

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.UpcomingEventsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.UpcomingEventsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetUpcomingEventsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
Expand All @@ -38,7 +39,7 @@ public async Task Run_WithException_ReturnsEmptyEventResults()
// Arrange
var exception = new Exception();

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.UpcomingEventsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.UpcomingEventsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetUpcomingEventsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
Expand All @@ -62,7 +63,7 @@ public async Task Run_WithValidParameters_ReturnsNoEventResults()
// Arrange
IEnumerable<UpcomingEvent> expectedEventResults = new List<UpcomingEvent>();

var loggerMock = Substitute.For<ILogger<OddsCollector.Functions.Functions.UpcomingEventsFunction>>();
var loggerMock = LoggerFactory.GetLoggerMock<OddsCollector.Functions.Functions.UpcomingEventsFunction>();

var clientStub = Substitute.For<IOddsApiClient>();
clientStub.GetUpcomingEventsAsync(Arg.Any<Guid>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
Expand Down

0 comments on commit 0551419

Please sign in to comment.