Mock IConfigurationSection para devolver una matriz de cadena

Nov 03 2020

Usando esta respuesta para simular los IConfigurationmétodos de una aplicación ASP.NET Core.

Necesito burlarme de un IConfigurationSectionpara devolver una stringmatriz.

Mi clase de configuración se ve así:

public class LoggingConfiguration
{
    public string ApplicationName { get; set; }
    public string[] Loggers { get; set; }
}

appsettings.json

{
    "Logging": {
        "LoggingConfiguration": {
              "ApplicationName": "Some app",
              "Loggers":  [ "DiskLogger", "MemoryLogger"],
              "DiskLogger": {
                  "SomeSettingOne" : "setting",
                  "SomeSettingTwo" : "setting",
               },
              "MemoryLogger": {
                  "AnotherSetting": "...",
               }
       }

Al preparar los simulacros, tengo dos problemas.

  1. No puedo averiguar cómo burlarme de un IConfigurationSectionque volvería string[]( loggers)
  2. Recibo una excepción cuando intento configurar el GetChildren()método en elLoggingSectionMock
public void Setup()
{
    var applicationNameConfigurationSectionMock = new Mock<IConfigurationSection>();
    applicationNameConfigurationSectionMock.Setup(m => m.Value).Returns(TestingApplicationName);

    var loggerNamesConfigurationSectionMock = new Mock<IConfigurationSection>();
    loggerNamesConfigurationSectionMock.Setup(m => m.GetChildren()).Returns(GetLoggerNamesSection);

    //Throwing Method Not Found exception
    LoggingSectionMock.Setup(m => m.GetChildren()).Returns(new List<IConfigurationSection>
        {applicationNameConfigurationSectionMock.Object, loggerNamesConfigurationSectionMock.Object});

    ConfigurationMock.Setup(m => m.GetSection($"{Logging}:{LoggingConfiguration}"))
        .Returns(() => LoggingSectionMock.Object);
}

private IEnumerable<IConfigurationSection> GetLoggerNamesSection()
{
    var loggerNamesConfigurationSections = new List<IConfigurationSection>();
    LoggerNames.ToList().ForEach(loggerName =>
    {
        var configSectionMock = new Mock<IConfigurationSection>();
        configSectionMock.Setup(m => m.Value).Returns(loggerName);
        loggerNamesConfigurationSections.Add(configSectionMock.Object);
    });
    return loggerNamesConfigurationSections;
}

Respuestas

3 PeterCsala Nov 03 2020 at 15:00

Como alternativa se puede tomar ventaja de ConfigurationBuilder's AddInMemoryCollection:

Proveedor de configuración de memoria de referencia

Preparar

IConfiguration configRoot = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string>
    {
        { "ApplicationName", "App" }, 
        { "Loggers:0", "1" },
        { "Loggers:1", "2" },
        { "Loggers:2", "3" }
    })
    .Build();

Uso

LoggingConfiguration config = configRoot.Get<LoggingConfiguration>();