[ASP.NET Core][Entity Framework Core] Logging for xUnit projects
Tags: aspnetcore, csharp, xunit, entityframeworkcore
Published: 2022-01-16 16:26:08

## Intro
To debug testing codes, I want to add loggers into my xUnit project.

* [【ASP.NET Core】【xUnit】【Moq】Add unit tests 1](https://dev.to/masanori_msl/asp-net-core-xunit-moq-add-unit-tests-1-26c8)
* [【ASP.NET Core】【xUnit】Testing Entity Framework Core applications with in-memory SQLite](https://dev.to/masanori_msl/aspnet-core-xunit-testing-entity-framework-core-applications-with-in-memory-sqlite-db4)

### Environments
* .NET ver.6.0.101
* Microsoft.NET.Test.Sdk ver.16.11.0
* xUnit ver.2.4.1
* xunit.runner.visualstudio ver.2.4.3
* coverlet.collector ver.3.1.0
* Microsoft.EntityFrameworkCore.Sqlite ver.6.0.1
* Moq ver.4.16.1

## Add loggers
In xUnit projects, I can't use "Console.WriteLine()" to log.
According to the document, to run tests in parallel, I should use "ITestOutputHelper".

#### BookTest.cs
```cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
using BookshelfSample.Books;
using BookshelfSampleTest.Models;
using BookshelfSample.Models;
using BookshelfSample.Models.SeedData;
using Xunit.Abstractions;

namespace BookshelfSampleTest.Books;
public class BooksTest: IDisposable
{
...
    private readonly ITestOutputHelper output;
    public BooksTest(ITestOutputHelper output)
    {
        this.output = output;
        this.output.WriteLine("Hello");
...
    }
    public void Dispose()
    {
        this.databaseFixture.Dispose();
    }
...
```

To output logs, I have to add "logger" option into "dotnet test" command.

```
dotnet test BookshelfSampleTest --logger "console;verbosity=detailed"
```

#### Result

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lah9ntvh0seitpr9yd6.png)

* [Capturing Output > xUnit.net](https://xunit.net/docs/capturing-output)

### How I shall run tests?

As same as this post, I run tests by ".NET Core Test Explorer" on VSCode.

* [【ASP.NET Core】【xUnit】【Moq】Add unit tests 1](https://dev.to/masanori_msl/asp-net-core-xunit-moq-add-unit-tests-1-26c8)

But the logs aren't written in "OUTPUT" tab.

```
Test run for /home/example/Documents/workspace/BookshelfSample/BookshelfSampleTest/bin/Debug/net6.0/BookshelfSampleTest.dll (.NETCoreApp,Version=v6.0)
Microsoft (R) Test Execution Command Line Tool Version 17.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
Results File: /tmp/test-explorer-kxye5v/0.trx

Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: < 1 ms - /home/example/Documents/workspace/BookshelfSample/BookshelfSampleTest/bin/Debug/net6.0/BookshelfSampleTest.dll (net6.0)
```

Because I use NLog in the ASP.NET Core project, I tried to use NLog in the xUnit project.
But I couldn't resolve the problem.

* [C# - How to use NLog in xUnit tests from .NET Core? - Stack Overflow](https://stackoverflow.com/questions/68100146/how-to-use-nlog-in-xunit-tests-from-net-core)

And I also tried "xunit.NLog". 
However, it didn't seem to be compatible with .NET 6. 

* [GitHub -  tdupont750/xunit.NLog](https://github.com/tdupont750/xunit.NLog)

So when I want to log some data to write test codes, I run tests by command.
After finishing creating them, I run them by ".NET Core Test Explorer".

## For Entity Framework Core projects
To log Entity Framework Core projects, I can add "ITestOutputHelper" into DbContext options.

#### SharedDatabaseFixture.cs
```cs
using BookshelfSample.Models;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Xunit.Abstractions;

namespace BookshelfSampleTest.Models;
public class SharedDatabaseFixture: IDisposable
{
    private readonly ITestOutputHelper output;
    private readonly SqliteConnection connection;
    public SharedDatabaseFixture(ITestOutputHelper output)
    {
        this.output = output;
        this.connection = new SqliteConnection("DataSource=:memory:");
        this.connection.Open();
    }
    public void Dispose() => this.connection.Dispose();
    public BookshelfContext CreateContext()
    {
        var result = new BookshelfContext(new DbContextOptionsBuilder<BookshelfContext>()
            .UseSqlite(this.connection)
            .EnableSensitiveDataLogging()
            .LogTo(this.output.WriteLine)
            .Options);
        result.Database.EnsureDeleted();    
        result.Database.EnsureCreated();
        return result;
    }
}
```

* [Entity Framework Core in Action, Second Edition](https://www.manning.com/books/entity-framework-core-in-action-second-edition)