Skip to content

Commit 7c40ecd

Browse files
committed
Add application layer tests
1 parent 283c651 commit 7c40ecd

File tree

5 files changed

+199
-76
lines changed

5 files changed

+199
-76
lines changed

RealTimeWeatherMonitoringTest/Application/Service/AutoParsingServiceShould.cs

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,64 @@
22
using Moq;
33
using RealTimeWeatherMonitoringApp.Application.Interfaces;
44
using RealTimeWeatherMonitoringApp.Application.Service;
5+
using RealTimeWeatherMonitoringTest.Common;
56
using RealTimeWeatherMonitoringTest.Domain.Models;
67
using Xunit;
78

89
namespace RealTimeWeatherMonitoringTest.Application.Service;
910

1011
public class AutoParsingServiceShould
1112
{
12-
private readonly AutoParsingService<TestData> _autoParsingService;
13-
14-
private readonly List<Mock<IParsingStrategy<TestData>>> _mockStrategies =
15-
[
16-
new Mock<IParsingStrategy<TestData>>(),
17-
new Mock<IParsingStrategy<TestData>>()
18-
];
19-
20-
private readonly List<string> _inputs =
21-
[
22-
"{ 'text': 'This can be parsed only by Strategy1' }",
23-
"<text>This can be parsed only by Strategy2</text>"
24-
];
13+
[Theory, AutoMoqData]
14+
public void AutoParse_NoParsingStrategyWorks_ReturnFailResult(
15+
string input,
16+
List<Mock<IParsingStrategy<TestData>>> strategyMocks,
17+
AutoParsingService<TestData> autoParsingService)
18+
{
19+
foreach (var mock in strategyMocks)
20+
autoParsingService.AddStrategy(mock.Object);
2521

26-
private const string InvalidInput = "This cannot be parsed by anything";
22+
var result = autoParsingService.AutoParse(input);
2723

28-
private TestData? _tryParseResult;
24+
result.Should().NotBeNull();
25+
result.Success.Should().BeFalse();
26+
result.Data.Should().BeNull();
27+
}
2928

30-
public AutoParsingServiceShould()
29+
[Theory, AutoMoqData]
30+
public void AutoParse_AStrategyWorks_ReturnSuccessResult(
31+
string input,
32+
TestData? resultData,
33+
Mock<IParsingStrategy<TestData>> strategyMock,
34+
AutoParsingService<TestData> autoParsingService)
3135
{
32-
_autoParsingService = new AutoParsingService<TestData>();
33-
_mockStrategies.ForEach(s => _autoParsingService.AddStrategy(s.Object));
36+
autoParsingService.AddStrategy(strategyMock.Object);
37+
strategyMock.Setup(s => s.TryParse(input, out resultData)).Returns(true);
3438

35-
for (var i = 0; i < _mockStrategies.Count; i++)
36-
{
37-
var i1 = i;
38-
_mockStrategies[i]
39-
.Setup(s => s.TryParse(_inputs[i1], out _tryParseResult))
40-
.Returns(true);
41-
}
42-
}
39+
var result = autoParsingService.AutoParse(input);
4340

44-
[Theory]
45-
[InlineData(0)]
46-
[InlineData(1)]
47-
public void AutoParse_UsesFirstSuccessfulStrategy(int inputsIndex)
48-
{
49-
var result = _autoParsingService.AutoParse(_inputs[inputsIndex]);
5041
result.Should().NotBeNull();
5142
result.Success.Should().BeTrue();
52-
53-
_mockStrategies[inputsIndex].Verify(s => s.TryParse(_inputs[inputsIndex], out _tryParseResult), Times.Once);
54-
_mockStrategies[inputsIndex].VerifyNoOtherCalls();
43+
result.Data.Should().BeSameAs(resultData);
5544
}
5645

57-
[Fact]
58-
public void AutoParse_ReturnsFailureWhenNoStrategiesSucceed()
46+
[Theory, AutoMoqData]
47+
public void AutoParse_MultipleStrategiesWork_UseFirstOne(
48+
string input,
49+
Mock<IParsingStrategy<TestData>> firstStrategyMock,
50+
Mock<IParsingStrategy<TestData>> secondStrategyMock,
51+
AutoParsingService<TestData> autoParsingService)
5952
{
60-
var result = _autoParsingService.AutoParse(InvalidInput);
61-
result.Should().NotBeNull();
62-
result.Success.Should().BeFalse();
53+
autoParsingService.AddStrategy(firstStrategyMock.Object);
54+
autoParsingService.AddStrategy(secondStrategyMock.Object);
55+
56+
TestData? dummy = null;
57+
firstStrategyMock.Setup(s => s.TryParse(input, out dummy)).Returns(true);
58+
secondStrategyMock.Setup(s => s.TryParse(input, out dummy)).Returns(true);
59+
60+
autoParsingService.AutoParse(input);
6361

64-
_mockStrategies.ForEach(strategy =>
65-
strategy.Verify(s =>
66-
s.TryParse(It.IsAny<string>(), out _tryParseResult), Times.Once));
62+
firstStrategyMock.Verify(s => s.TryParse(input, out dummy), Times.Once);
63+
secondStrategyMock.Verify(s => s.TryParse(input, out dummy), Times.Never);
6764
}
6865
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using AutoFixture.Xunit2;
2+
using FluentAssertions;
3+
using Moq;
4+
using RealTimeWeatherMonitoringApp.Application.Service;
5+
using RealTimeWeatherMonitoringApp.Domain.Common;
6+
using RealTimeWeatherMonitoringTest.Common;
7+
using Xunit;
8+
9+
namespace RealTimeWeatherMonitoringTest.Application.Service;
10+
11+
public class BotEventDispatcherShould
12+
{
13+
[Theory, AutoMoqData]
14+
public void Publish_Always_NotifySubscribers(
15+
BotEventArgs eventArgs,
16+
Mock<EventHandler<BotEventArgs>> mockEventHandler,
17+
BotEventDispatcher botEventDispatcher)
18+
{
19+
botEventDispatcher.OnBotNotification += mockEventHandler.Object;
20+
21+
botEventDispatcher.Publish(eventArgs);
22+
23+
mockEventHandler.Verify(
24+
h => h.Invoke(It.IsAny<object>(), It.IsAny<BotEventArgs>()),
25+
Times.Once);
26+
}
27+
28+
[Theory, AutoData]
29+
public void Publish_Always_SendSubscribersTheSameEventArgs(
30+
BotEventArgs eventArgs,
31+
BotEventDispatcher botEventDispatcher)
32+
{
33+
BotEventArgs? capturedEventArgs = null;
34+
botEventDispatcher.OnBotNotification += (_, args) => capturedEventArgs = args;
35+
36+
botEventDispatcher.Publish(eventArgs);
37+
38+
capturedEventArgs.Should().NotBeNull()
39+
.And.BeSameAs(eventArgs);
40+
}
41+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using AutoFixture.Xunit2;
2+
using Moq;
3+
using RealTimeWeatherMonitoringApp.Application.Interfaces;
4+
using RealTimeWeatherMonitoringApp.Application.Service;
5+
using RealTimeWeatherMonitoringApp.Domain.Common;
6+
using RealTimeWeatherMonitoringApp.Domain.Interfaces;
7+
using RealTimeWeatherMonitoringApp.Domain.Interfaces.Service;
8+
using RealTimeWeatherMonitoringTest.Common;
9+
using RealTimeWeatherMonitoringTest.Domain.Models;
10+
using Xunit;
11+
12+
namespace RealTimeWeatherMonitoringTest.Application.Service;
13+
14+
public class BotEventManagerShould
15+
{
16+
[Theory, AutoMoqData]
17+
public void Attach_WhenDataChanges_BotControllersReactAndPublishToServices(
18+
DataChangeEventArgs<TestData> dataChangeEventArgs,
19+
BotEventArgs botEventArgs,
20+
List<Mock<IBotController<TestData>>> botControllerMocks,
21+
Mock<IBotPublishingService> botPublishingServiceMock,
22+
Mock<IDataChangeNotifier<TestData>> dataChangeNotifierMock,
23+
[Frozen] Mock<IBotControllerService<TestData>> botControllerServiceMock,
24+
BotEventManager<TestData> botEventManager)
25+
{
26+
foreach (var botControllerMock in botControllerMocks)
27+
botControllerMock
28+
.Setup(c => c.React(dataChangeEventArgs))
29+
.Callback(() => botPublishingServiceMock.Object.Publish(botEventArgs))
30+
.Returns(botEventArgs);
31+
32+
botControllerServiceMock
33+
.Setup(s => s.GetBotControllers(botPublishingServiceMock.Object))
34+
.Returns(botControllerMocks.Select(m => m.Object));
35+
36+
botEventManager.Attach(dataChangeNotifierMock.Object, botPublishingServiceMock.Object);
37+
dataChangeNotifierMock.Raise(n => n.OnDataChange += null, dataChangeEventArgs);
38+
39+
foreach (var botControllerMock in botControllerMocks)
40+
botControllerMock.Verify(c => c.React(dataChangeEventArgs), Times.Once);
41+
42+
botPublishingServiceMock.Verify(s => s.Publish(botEventArgs),
43+
Times.Exactly(botControllerMocks.Count));
44+
}
45+
}
Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,53 @@
1+
using AutoFixture.Xunit2;
12
using FluentAssertions;
23
using Moq;
34
using RealTimeWeatherMonitoringApp.Application.Common;
45
using RealTimeWeatherMonitoringApp.Application.Interfaces;
56
using RealTimeWeatherMonitoringApp.Application.Interfaces.Service;
67
using RealTimeWeatherMonitoringApp.Application.Service;
8+
using RealTimeWeatherMonitoringTest.Common;
79
using RealTimeWeatherMonitoringTest.Domain.Models;
810
using Xunit;
911

1012
namespace RealTimeWeatherMonitoringTest.Application.Service;
1113

1214
public class DataProcessingServiceShould
1315
{
14-
private readonly DataProcessingService<TestData> _dataProcessor;
15-
16-
private readonly Mock<IAutoParsingService<TestData>> _mockAutoParsingService = new();
17-
private readonly Mock<IDataReceiver<TestData>> _mockReceiver = new();
18-
19-
private const string InvalidInput = "This input cannot be parsed";
20-
private const string ValidInput = "<test>XML Data</test>";
16+
[Theory, AutoMoqData]
17+
public void Process_SuccessfulParsing_SendDataToReceiver(
18+
string goodInput,
19+
ParsingResult<TestData> parsingResult,
20+
[Frozen] Mock<IAutoParsingService<TestData>> autoParsingServiceMock,
21+
[Frozen] Mock<IDataReceiver<TestData>> dataReceiverMock,
22+
DataProcessingService<TestData> dataProcessingService)
23+
{
24+
parsingResult.Success = true;
25+
autoParsingServiceMock
26+
.Setup(s => s.AutoParse(goodInput))
27+
.Returns(parsingResult);
2128

22-
private readonly ParsingResult<TestData> _badResult = new(false, "Parsing failed");
23-
private readonly ParsingResult<TestData> _goodResult = new(true, "Parsing succeeded");
29+
var result = dataProcessingService.Process(goodInput);
2430

25-
public DataProcessingServiceShould()
26-
{
27-
_dataProcessor = new DataProcessingService<TestData>(_mockAutoParsingService.Object, _mockReceiver.Object);
28-
_mockAutoParsingService.Setup(s => s.AutoParse(InvalidInput)).Returns(_badResult);
29-
_mockAutoParsingService.Setup(s => s.AutoParse(ValidInput)).Returns(_goodResult);
31+
dataReceiverMock.Verify(r => r.Receive(parsingResult.Data), Times.Once);
32+
result.Should().BeSameAs(parsingResult);
3033
}
3134

32-
[Theory]
33-
[InlineData(InvalidInput)]
34-
[InlineData(ValidInput)]
35-
public void Process_Always_ParseAndReturnResult(string parsingInput)
35+
[Theory, AutoMoqData]
36+
public void Process_FailedParsing_NotSendToReceiver(
37+
string badInput,
38+
ParsingResult<TestData> parsingResult,
39+
[Frozen] Mock<IAutoParsingService<TestData>> autoParsingServiceMock,
40+
[Frozen] Mock<IDataReceiver<TestData>> dataReceiverMock,
41+
DataProcessingService<TestData> dataProcessingService)
3642
{
37-
var result = _dataProcessor.Process(parsingInput);
38-
result.Should().NotBeNull();
39-
_mockAutoParsingService.Verify(s => s.AutoParse(parsingInput), Times.Once);
40-
}
43+
parsingResult.Success = false;
44+
autoParsingServiceMock
45+
.Setup(s => s.AutoParse(badInput))
46+
.Returns(parsingResult);
4147

42-
[Fact]
43-
public void Process_OnParsingFail_NotSendToReceiver()
44-
{
45-
_dataProcessor.Process(InvalidInput);
46-
_mockReceiver.Verify(r => r.Receive(It.IsAny<TestData>()), Times.Never);
47-
}
48+
var result = dataProcessingService.Process(badInput);
4849

49-
[Fact]
50-
public void Process_OnSuccessfulParsing_SendResultToReceiver()
51-
{
52-
_dataProcessor.Process(ValidInput);
53-
_mockReceiver.Verify(r => r.Receive(It.IsAny<TestData>()), Times.Once);
50+
dataReceiverMock.Verify(r => r.Receive(It.IsAny<TestData>()), Times.Never);
51+
result.Should().BeSameAs(parsingResult);
5452
}
5553
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using AutoFixture.Xunit2;
2+
using FluentAssertions;
3+
using Moq;
4+
using RealTimeWeatherMonitoringApp.Application.Service;
5+
using RealTimeWeatherMonitoringApp.Domain.Common;
6+
using RealTimeWeatherMonitoringTest.Common;
7+
using RealTimeWeatherMonitoringTest.Domain.Models;
8+
using Xunit;
9+
10+
namespace RealTimeWeatherMonitoringTest.Application.Service;
11+
12+
public class MonitoringServiceShould
13+
{
14+
[Theory, AutoMoqData]
15+
public void Receive_Always_InvokeSubscribers(
16+
TestData data,
17+
Mock<EventHandler<DataChangeEventArgs<TestData>>> mockEventHandler,
18+
MonitoringService<TestData> monitoringService)
19+
{
20+
monitoringService.OnDataChange += mockEventHandler.Object;
21+
22+
monitoringService.Receive(data);
23+
24+
mockEventHandler.Verify(
25+
h => h.Invoke(It.IsAny<object>(), It.IsAny<DataChangeEventArgs<TestData>>()),
26+
Times.Once);
27+
}
28+
29+
[Theory, AutoData]
30+
public void Receive_Always_SendSubscribersTheSameData(
31+
TestData data,
32+
MonitoringService<TestData> monitoringService)
33+
{
34+
DataChangeEventArgs<TestData>? capturedEventArgs = null;
35+
monitoringService.OnDataChange += (_, args) => capturedEventArgs = args;
36+
37+
monitoringService.Receive(data);
38+
39+
capturedEventArgs.Should().NotBeNull();
40+
capturedEventArgs.NewData.Should().BeSameAs(data);
41+
}
42+
}

0 commit comments

Comments
 (0)