Модульное тестирование (xUnit) Служба журналирования NLog под .NET Core - PullRequest
0 голосов
/ 08 апреля 2019

.NET Core 2.1 NLog 4.6 xUnit 2.3.1

У меня есть библиотека классов с xUnit, которая вызывает отдельную библиотеку с API-интерфейсами на основе REST, которая отвечает за создание различных журналов для системы.

Поскольку библиотека классов модульного тестирования напрямую вызывает контроллер API на основе REST, класс Startup класса не загружается, поэтому я не верю, что NLog настраивается.Это нужно будет сделать в библиотеке классов модульных тестов, но я не могу понять это.

Я могу загрузить конфигурацию nlog API на основе REST из вызывающей библиотеки и затем выполнить NLogs непосредственно из LogManager, но реализация NLog, явно используемая в API на основе REST, не регистрирует и не выдает никакой ошибки.,

Если я использую мыльный клиент, такой как SOAPUI, и вызываю библиотеку классов REST, журналы создаются, как ожидается.Это означает, что библиотека классов модульных тестов неправильно настраивает ведение журнала.

// Unit Test's base class for wiring up DI and other configuration including Logging
public BaseTests()
{
    // Configuration
    string loggingServiceAPIPath = @"../../../../../../LoggingService/API/CM.LoggingService.API";
    var builder = new ConfigurationBuilder().SetBasePath(Path.GetFullPath(loggingServiceAPIPath)).AddJsonFile("appsettings.json");
    var configuration = builder.Build();

    // Configure logging
    LogManager.Configuration = new XmlLoggingConfiguration(Path.GetFullPath($"{ loggingServiceAPIPath }/nlog.config"));

    // Application-Wide Services
    IServiceCollection services = new ServiceCollection();
    services.AddMvc();
    services.AddLogging();

    services.AddSingleton(configuration);
    services.AddSingleton<ILoggerFactory, LoggerFactory>();
    services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
    services.AddSingleton<IMemoryCache, MemoryCache>();
    services.AddSingleton<ILoggingServiceController, LoggingServiceController>();
    services.AddApplicationServices();

    services.AddOptions();
    services.ConfigureConfigServerClientOptions(configuration);
    services.AddConfiguration(configuration);
    services.Configure<ConfigServerData>(configuration);
    this._serviceProvider = services.BuildServiceProvider();

    // Persist configuration
    IMemoryCache iMemoryCache = this._serviceProvider.GetService<IMemoryCache>();
    IOptionsSnapshot<ConfigServerData> iConfigServerData = this._serviceProvider.GetService<IOptionsSnapshot<ConfigServerData>>();
    if (iMemoryCache != null && iConfigServerData != null) { iMemoryCache.Set(CM.Common.Constants.ConfigKey, iConfigServerData.Value); }
} 

// Unit Test being called from a class library
[Fact]
public async void Test_LogDebugSuccess()
{
    LoggingServiceRequest request = new LoggingServiceRequest
    {
        ErrorException = new Exception(),
        Message = System.Reflection.MethodBase.GetCurrentMethod().Name
    };

    // This is not capturing NLog probably due to not being called in a hosted environment.
    var result = await 
    this._iLoggingServiceController.LogDebug(request);

    // Assert
    Assert.Null(result as NotFoundObjectResult);
    var okObjectResult = result as OkObjectResult;
    Assert.True((okObjectResult != null &&
                 okObjectResult.StatusCode.GetValueOrDefault(0) == Convert.ToInt32(System.Net.HttpStatusCode.OK)), "Log was not created.");
}

// LoggingService
public class Program
{
    /// <summary>
    /// Main
    /// </summary>
    /// <param name="args">Arguments</param>
    public static void Main(string[] args)
    {
        // NLog: setup the logger first to catch all errors
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        try
        {
            logger.Debug("Init Main");                
            Program.BuildWebHost(args).Run();
        }
        catch (Exception ex)
        {
            logger.Error(ex, $"Stopped program because of exception: { ex.Message }");
            throw;
        }
        finally
        {
            // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
            NLog.LogManager.Shutdown();
        }
    }

    /// <summary>
    /// Build WebHost
    /// </summary>
    /// <param name="args">Arguments</param>
    /// <returns>WebHost interface</returns>
    public static IWebHost BuildWebHost(string[] args)
    {
        try
        {
            var config = WebHost.CreateDefaultBuilder(args)
                        .CaptureStartupErrors(false)
                        .AddConfigServer()
                        .UseStartup<Startup>()
                        .ConfigureLogging(logging =>
                        {
                            logging.ClearProviders();
                            logging.SetMinimumLevel(LogLevel.Trace);
                        })
                        .UseNLog()  // NLog: setup NLog for Dependency injection
                        .Build();

            return config;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(
            config =>
            {
                config.Filters.Add(typeof(CustomExceptionFilter));
            }
        );

    // Add memory cache
    services.AddMemoryCache();

    services.AddMvc();

    services.AddCors(o => o.AddPolicy("corspolicy",
        builder => builder.AllowAnyOrigin()
        .AllowAnyHeader()
        .AllowAnyMethod()));

    services.AddSingleton(this.Configuration);

    // Application-Wide Services
    services.AddApplicationServices();

    // Configuration
    services.AddOptions();
    services.ConfigureConfigServerClientOptions(this.Configuration);
    services.AddConfiguration(this.Configuration);
    services.Configure<ConfigServerData>(this.Configuration);

    // Configure Swagger
    services.AddSwaggerGen(s =>
    {
        s.SwaggerDoc("v1", new Info { Title = "CM LoggingService APIs", Version = "V1" });
    });
}

public void Configure(IApplicationBuilder iApplicationBuilder, IHostingEnvironment iHostingEnvironment, IConfigurationManager iConfigurationManager, IMemoryCache iMemoryCache, IApplicationLifetime iApplicationLifetime, ILogger<LoggingServiceController> iLogger)
{
    if (iHostingEnvironment.IsDevelopment() == true)
    {
        iApplicationBuilder.UseDeveloperExceptionPage();
        iApplicationBuilder.UseStatusCodePages();

        iApplicationBuilder.UseDatabaseErrorPage();
        iApplicationBuilder.UseBrowserLink();
    }
    if (iHostingEnvironment.IsProduction() == false)
    {
        // Swagger - API Documentation
        iApplicationBuilder.UseSwagger();
        iApplicationBuilder.UseSwaggerUI(s =>
        {
            s.SwaggerEndpoint("./v1/swagger.json", "CM LoggingService APIs");
        });
    }

    // Persist Steeltoe configuration
    iConfigurationManager.Init();
    if (iMemoryCache != null && iConfigurationManager != null) { iMemoryCache.Set(CM.Common.Constants.MEMORYCACHE_CONFIGURATIONMANAGER_KEY, iConfigurationManager); }
    iConfigurationManager.LogConfiguration();

    // Configure global exception handler
    iApplicationBuilder.ConfigureExceptionHandler(iLogger);

    iApplicationBuilder.UseMvc();

    // Application Events
    iApplicationLifetime.ApplicationStarted.Register(this.OnApplicationStarted);
    iApplicationLifetime.ApplicationStopped.Register(this.OnApplicationStopping);
}

public class LoggingServiceController : Controller, ILoggingServiceController
{
    private readonly ILogger<LoggingServiceController> _iLogger = null;
    private readonly ILoggingServiceDomainController _iLoggingServiceDomainController = null;

    public LoggingServiceController(ILogger<LoggingServiceController> iLogger, ILoggingServiceDomainController iLoggingServiceDomainController)
    {
        this._iLogger = iLogger;
        this._iLoggingServiceDomainController = iLoggingServiceDomainController;
    }

    [HttpPost("LogError")]
    public async Task<IActionResult> LogError([FromBody] LoggingServiceRequest request)
    {
        bool result = false;

        try
        {
            // Validation
            if (ModelState.IsValid == false)
            {
                this._iLogger.LogError($"{ CM.Common.ExceptionHandling.ExceptionTypes.VALIDATION }: { typeof(LoggingServiceRequest).Name } (request) is not valid.");
                return BadRequest();
            }

            // Log
            result = this._iLogger.LogError(request.ErrorException, request.Message, request.Args);
            if (result == false) { return NotFound(); }
        }
        catch (Exception ex)
        {
            this._iLogger.LogError(ex, $"{ CM.Common.ExceptionHandling.ExceptionTypes.UNSPECIFIED }: { ex.Message }");
        }

        return Ok(result);
    }
}

...