diff --git a/src/Abstractions/ConfigurationValidation.cs b/src/Abstractions/ConfigurationValidation.cs new file mode 100644 index 00000000..4f24c297 --- /dev/null +++ b/src/Abstractions/ConfigurationValidation.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Omex.Extensions.Abstractions +{ + /// + /// Class provides common validation methods for Microsoft.Extensions.IConfiguration + /// + public static class ConfigurationValidation + { + /// + /// Omex workaround around IConfigurationSection.Get() returning null variables. + /// + /// Type needed from the configuration section + /// IConfiguration object + /// Name of configuration section to get the object from + /// Non-nullable object of type T + /// If the type T is not found in the given section of the configuration + public static T GetNonNullableOrThrow(IConfiguration configuration, string sectionName) + { + return configuration.GetSection(sectionName).Get() + ?? throw new InvalidOperationException($"{nameof(T)} missing in the {sectionName} section of the configuration"); + } + } +} diff --git a/src/Abstractions/Microsoft.Omex.Extensions.Abstractions.csproj b/src/Abstractions/Microsoft.Omex.Extensions.Abstractions.csproj index ec9b9340..a4ca000b 100644 --- a/src/Abstractions/Microsoft.Omex.Extensions.Abstractions.csproj +++ b/src/Abstractions/Microsoft.Omex.Extensions.Abstractions.csproj @@ -14,6 +14,7 @@ + diff --git a/tests/Abstractions.UnitTests/ConfigurationValidationTests.cs b/tests/Abstractions.UnitTests/ConfigurationValidationTests.cs new file mode 100644 index 00000000..f0527e78 --- /dev/null +++ b/tests/Abstractions.UnitTests/ConfigurationValidationTests.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.Configuration; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Omex.Extensions.Abstractions.UnitTests +{ + [TestClass] + public class ConfigurationValidationTests + { + [TestMethod] + public void GetNonNullableOrThrow_WhenValueNotNull() + { + // prepare mocks + string sectionKeyInt = "SectionKeyInt"; + string sectionKeyString = "SectionKeyString"; + string configValueInt = "5"; + string configValueString = "asdf"; + + Mock mockSectionInt = new Mock(); + Mock mockSectionString = new Mock(); + Mock mockConfig = new Mock(); + + mockSectionInt.Setup(x => x.Value).Returns(configValueInt); + mockSectionString.Setup(x => x.Value).Returns(configValueString); + mockConfig.Setup(x => x.GetSection(It.Is(k => k == sectionKeyInt))).Returns(mockSectionInt.Object); + mockConfig.Setup(x => x.GetSection(It.Is(k => k == sectionKeyString))).Returns(mockSectionString.Object); + + // assert + int resultInt = ConfigurationValidation.GetNonNullableOrThrow(mockConfig.Object, sectionKeyInt); + string resultString = ConfigurationValidation.GetNonNullableOrThrow(mockConfig.Object, sectionKeyString); + Assert.AreEqual(resultInt, int.Parse(configValueInt)); + Assert.AreEqual(resultString, configValueString); + } + + + [TestMethod] + public void GetNonNullableOrThrow_WhenValueNull() + { + // prepare mocks + string sectionKey = "SectionKey"; + + Mock mockSection = new Mock(); + Mock mockConfig = new Mock(); + + mockSection.Setup(x => x.Value).Returns((string?)null); + mockConfig.Setup(x => x.GetSection(It.Is(k => k == sectionKey))).Returns(mockSection.Object); + + // assert + Assert.ThrowsException(() => ConfigurationValidation.GetNonNullableOrThrow(mockConfig.Object, sectionKey)); + } + + [TestMethod] + public void GetNonNullableOrThrow_WhenWrongType() + { + // prepare mocks + string sectionKey = "SectionKey"; + string sectionKeyString = "SectionKeyString"; + + Mock mockSection = new Mock(); + Mock mockConfig = new Mock(); + + mockSection.Setup(x => x.Value).Returns(sectionKeyString); + mockConfig.Setup(x => x.GetSection(It.Is(k => k == sectionKey))).Returns(mockSection.Object); + + // assert + Assert.ThrowsException(() => ConfigurationValidation.GetNonNullableOrThrow(mockConfig.Object, sectionKey)); + } + } +}