From a208492e0c9fe3798aded5c307c152f89a3f31f2 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin Nutiu Date: Sat, 30 Nov 2019 17:19:56 +0200 Subject: [PATCH] Add tests for NucuCar.Sensor environment sensor's grpc services --- .../Telemetry/TelemetryPublisher.cs | 7 +++ .../EnvironmentSensor/Bme680Sensor.cs | 17 ++++-- .../EnvironmentSensor/Bme680Worker.cs | 6 ++ NucuCar.Sensors/Telemetry/SensorTelemetry.cs | 8 ++- .../Bme680GrpcServiceTest.cs | 55 +++++++++++++++++++ NucuCar.UnitTests/NucuCar.UnitTests.csproj | 22 ++++++++ NucuCar.sln | 6 ++ 7 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 NucuCar.UnitTests/NucuCar.Sensors.Tests/EnvironmentSensor.Tests/Bme680GrpcServiceTest.cs create mode 100644 NucuCar.UnitTests/NucuCar.UnitTests.csproj diff --git a/NucuCar.Domain/Telemetry/TelemetryPublisher.cs b/NucuCar.Domain/Telemetry/TelemetryPublisher.cs index 0acbfb4..79fdaa9 100644 --- a/NucuCar.Domain/Telemetry/TelemetryPublisher.cs +++ b/NucuCar.Domain/Telemetry/TelemetryPublisher.cs @@ -11,6 +11,13 @@ namespace NucuCar.Domain.Telemetry /// public abstract class TelemetryPublisher : IDisposable { + /// + /// Parameter less constructor, mainly used for testing. + /// + public TelemetryPublisher() + { + } + /// /// Raw connection string that is used to connect to the cloud service. Should be parsed if required. /// diff --git a/NucuCar.Sensors/EnvironmentSensor/Bme680Sensor.cs b/NucuCar.Sensors/EnvironmentSensor/Bme680Sensor.cs index 2c5c7f4..aedcba5 100644 --- a/NucuCar.Sensors/EnvironmentSensor/Bme680Sensor.cs +++ b/NucuCar.Sensors/EnvironmentSensor/Bme680Sensor.cs @@ -24,6 +24,11 @@ namespace NucuCar.Sensors.EnvironmentSensor private EnvironmentSensorMeasurement _lastMeasurement; private SensorStateEnum _sensorStateEnum; + public Bme680Sensor() + { + + } + public Bme680Sensor(ILogger logger, IOptions options) { _sensorStateEnum = SensorStateEnum.Uninitialized; @@ -39,12 +44,14 @@ namespace NucuCar.Sensors.EnvironmentSensor } } - public EnvironmentSensorMeasurement GetMeasurement() + // TODO Make more generic, Add interface and remove virtual + public virtual EnvironmentSensorMeasurement GetMeasurement() { return _lastMeasurement; } - public SensorStateEnum GetState() + // TODO: Add interface and remove virtual + public virtual SensorStateEnum GetState() { return _sensorStateEnum; } @@ -54,7 +61,7 @@ namespace NucuCar.Sensors.EnvironmentSensor _bme680?.Dispose(); } - internal void InitializeSensor() + public void InitializeSensor() { if (_sensorStateEnum == SensorStateEnum.Initialized) { @@ -85,8 +92,8 @@ namespace NucuCar.Sensors.EnvironmentSensor _sensorStateEnum = SensorStateEnum.Error; } } - - internal async Task TakeMeasurement() + + public async Task TakeMeasurement() { if (_sensorStateEnum != SensorStateEnum.Initialized) { diff --git a/NucuCar.Sensors/EnvironmentSensor/Bme680Worker.cs b/NucuCar.Sensors/EnvironmentSensor/Bme680Worker.cs index 85f510c..3a48871 100644 --- a/NucuCar.Sensors/EnvironmentSensor/Bme680Worker.cs +++ b/NucuCar.Sensors/EnvironmentSensor/Bme680Worker.cs @@ -16,6 +16,7 @@ namespace NucuCar.Sensors.EnvironmentSensor public class Bme680Worker : BackgroundService { private readonly bool _telemetryEnabled; + private readonly bool _serviceEnabled; private readonly int _measurementInterval; private readonly ILogger _logger; private readonly TelemetryPublisher _telemetryPublisher; @@ -27,6 +28,7 @@ namespace NucuCar.Sensors.EnvironmentSensor { _logger = logger; _telemetryEnabled = options.Value.TelemetryEnabled; + _serviceEnabled = options.Value.ServiceEnabled; _measurementInterval = options.Value.MeasurementInterval; _telemetryPublisher = sensorTelemetry.Publisher; _bme680Sensor = bme680Sensor; @@ -34,6 +36,10 @@ namespace NucuCar.Sensors.EnvironmentSensor protected override async Task ExecuteAsync(CancellationToken stoppingToken) { + if (_serviceEnabled) + { + return; + } if (_telemetryEnabled) { _telemetryPublisher?.RegisterTelemeter(_bme680Sensor); diff --git a/NucuCar.Sensors/Telemetry/SensorTelemetry.cs b/NucuCar.Sensors/Telemetry/SensorTelemetry.cs index b896745..48a39be 100644 --- a/NucuCar.Sensors/Telemetry/SensorTelemetry.cs +++ b/NucuCar.Sensors/Telemetry/SensorTelemetry.cs @@ -1,13 +1,19 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NucuCar.Domain.Telemetry; +// ReSharper disable ClassWithVirtualMembersNeverInherited.Global namespace NucuCar.Sensors.Telemetry { public class SensorTelemetry { - public TelemetryPublisher Publisher { get; } + public TelemetryPublisher Publisher { get; set; } + public SensorTelemetry() + { + + } + public SensorTelemetry(ILogger logger, IOptions options) { if (options.Value.ServiceEnabled) diff --git a/NucuCar.UnitTests/NucuCar.Sensors.Tests/EnvironmentSensor.Tests/Bme680GrpcServiceTest.cs b/NucuCar.UnitTests/NucuCar.Sensors.Tests/EnvironmentSensor.Tests/Bme680GrpcServiceTest.cs new file mode 100644 index 0000000..8af2c42 --- /dev/null +++ b/NucuCar.UnitTests/NucuCar.Sensors.Tests/EnvironmentSensor.Tests/Bme680GrpcServiceTest.cs @@ -0,0 +1,55 @@ +using System; +using Grpc.Core; +using Microsoft.Extensions.Logging; +using Moq; +using NucuCar.Sensors.EnvironmentSensor; +using NucuCarSensorsProto; +using Xunit; +using Xunit.Abstractions; + +namespace NucuCar.UnitTests.NucuCar.Sensors.Tests.EnvironmentSensor.Tests +{ + public class Bme680GrpcServiceTest + { + private readonly ITestOutputHelper _testOutputHelper; + private readonly Mock> _mockLogger; + private readonly Mock _mockSensor; + + + public Bme680GrpcServiceTest(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + _mockLogger = new Mock>(); + _mockSensor = new Mock(); + } + + + [Fact] + public void Test_GetSensorState() + { + var service = new Bme680GrpcService(_mockLogger.Object, _mockSensor.Object); + var result = service.GetSensorState(null, null).Result; + + // Default sensor state is error + Assert.Equal(SensorStateEnum.Error, result.State); + + // Verify that the sensor get state method is called. + _mockSensor.Verify(s => s.GetState(), Times.AtLeastOnce()); + + _mockSensor.Setup(s => s.GetState()).Returns(SensorStateEnum.Initialized); + result = service.GetSensorState(null, null).Result; + Assert.Equal(SensorStateEnum.Initialized, result.State); + } + + [Fact] + public void Test_GetSensorMeasurement() + { + var service = new Bme680GrpcService(_mockLogger.Object, _mockSensor.Object); + service.GetSensorMeasurement(null, null); + + // Verify that the sensor get measurement method is called. + _mockSensor.Verify(s => s.GetMeasurement(), Times.AtLeastOnce()); + + } + } +} \ No newline at end of file diff --git a/NucuCar.UnitTests/NucuCar.UnitTests.csproj b/NucuCar.UnitTests/NucuCar.UnitTests.csproj new file mode 100644 index 0000000..20bed8f --- /dev/null +++ b/NucuCar.UnitTests/NucuCar.UnitTests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp3.0 + + false + + + + + + + + + + + + + + + + diff --git a/NucuCar.sln b/NucuCar.sln index 1945c3c..7b09eb3 100644 --- a/NucuCar.sln +++ b/NucuCar.sln @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NucuCar.TestClient", "NucuC EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NucuCar.Domain", "NucuCar.Domain\NucuCar.Domain.csproj", "{36BDA186-4C90-43C6-8991-A16DE245F91A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NucuCar.UnitTests", "NucuCar.UnitTests\NucuCar.UnitTests.csproj", "{C6F07921-1052-4945-911E-F328A622F229}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +26,9 @@ Global {36BDA186-4C90-43C6-8991-A16DE245F91A}.Debug|Any CPU.Build.0 = Debug|Any CPU {36BDA186-4C90-43C6-8991-A16DE245F91A}.Release|Any CPU.ActiveCfg = Release|Any CPU {36BDA186-4C90-43C6-8991-A16DE245F91A}.Release|Any CPU.Build.0 = Release|Any CPU + {C6F07921-1052-4945-911E-F328A622F229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6F07921-1052-4945-911E-F328A622F229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6F07921-1052-4945-911E-F328A622F229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6F07921-1052-4945-911E-F328A622F229}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal