# Évaluation de l'unité Umami.Net M SK1 Enregistrement dans ASP.NET Core

# Introduction

I'je suis un noob relatif qui utilise Moq M SK1oui I 'j'ai connaissance des controverses) et j'essayais de tester un nouveau service I\'\I'ajoute à Umami\MST5\Net\MSC6\UmiData\.\Ce service me permet d'extraire des données de mon instance Umami pour les utiliser dans des choses comme le tri des articles par popularité, etc.

[TOC]

<!--category-- xUnit, ASP.NET Core -->
<datetime class="hidden">2024-09-04T13:22</datetime>

# Le problème

J'ai essayé d'ajouter un test simple pour la fonction de connexion que je dois utiliser lors du retrait des données.
Comme vous le voyez, ' est un service simple qui passe un nom d'utilisateur et un mot de passe à `/api/auth/login` et obtient un résultat. Si le résultat est couronné de succès, il stocke le token dans `_token` et fixe le champ `Authorization` inscription au titre de la `HttpClient` à utiliser dans les demandes futures.

```csharp
public class AuthService(HttpClient httpClient, UmamiDataSettings umamiSettings, ILogger<AuthService> logger)
{
    private string _token = string.Empty;
    public HttpClient HttpClient => httpClient;

    public async Task<bool> LoginAsync()
    {
        var loginData = new
        {
            username = umamiSettings.Username,
            password = umamiSettings.Password
        };

        var content = new StringContent(JsonSerializer.Serialize(loginData), Encoding.UTF8, "application/json");
        var response = await httpClient.PostAsync("/api/auth/login", content);

        if (response.IsSuccessStatusCode)
        {
            var authResponse = await response.Content.ReadFromJsonAsync<AuthResponse>();

            if (authResponse == null)
            {
                logger.LogError("Login failed");
                return false;
            }

            _token = authResponse.Token;
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
            logger.LogInformation("Login successful");
            return true;
        }

        logger.LogError("Login failed");
        return false;
    }
}
```

Maintenant, j’ai également voulu tester contre le loggeur pour s’assurer qu’il enregistre les messages corrects. `Microsoft.Extensions.Logging` namespace et je voulais vérifier que les messages de log corrects étaient écrits au logger.

Dans Moq, il y a une BUNCH de postes autour du test d’enregistrement qui ont tous cette forme de base (de https ://adamstorr.coMSC4ukM SK5blogMNK6mockingMEK7iloggerMZK8avecMMK9moqMRK10

```csharp
public static Mock<ILogger<T>> VerifyDebugWasCalled<T>(this Mock<ILogger<T>> logger, string expectedMessage)
{
    Func<object, Type, bool> state = (v, t) => v.ToString().CompareTo(expectedMessage) == 0;
    
    logger.Verify(
        x => x.Log(
            It.Is<LogLevel>(l => l == LogLevel.Debug),
            It.IsAny<EventId>(),
            It.Is<It.IsAnyType>((v, t) => state(v, t)),
            It.IsAny<Exception>(),
            It.Is<Func<It.IsAnyType, Exception, string>>((v, t) => true)));

    return logger;
}
```

Toutefois, en raison des modifications récentes de Moq', (ItM SK2IsAnyType est maintenant désuet ) et ASPMska4NET CoreMske5, les changements apportés aux Valeurs Logiques Formatées J'ai eu du mal à le faire fonctionner.

J’ai essayé une BUNCH de versions et de variantes, mais cela a toujours échoué.

# La solution

Alors en lisant un certain nombre de messages sur GitHub, j’ai découvert un post de David Fowler ( mon ancien collègue et maintenant le lord de .NET) qui a montré une façon simple d’essayer l’enregistrement dans ASPM SK3NET CoreMSC4
Il s'agit de *nouveau pour moi* `Microsoft.Extensions.Diagnostics.Testing` [paquet](https://github.com/dotnet/extensions/tree/main/src/Libraries/Microsoft.Extensions.Diagnostics.Testing) qui a quelques extensions vraiment utiles pour tester l’enregistrement.

Alors au lieu de toutes les choses Moq, j’ai simplement ajouté `Microsoft.Extensions.Diagnostics.Testing` et j’ai ajouté ce qui suit à mes tests.

```csharp
    public IServiceProvider GetServiceProvider (string username="username", string password="password")
    {
        var services = new ServiceCollection();
        var mockLogger = new FakeLogger<UmamiDataService>();
        var authLogger = new FakeLogger<AuthService>();
        services.AddScoped<ILogger<UmamiDataService>>(_ => mockLogger);
        services.AddScoped<ILogger<AuthService>>(_ => authLogger);
        services.SetupUmamiData(username, password);
        return  services.BuildServiceProvider();
        
    }
```

Vous verrez que cela crée mon ServiceCollection, ajoute le nouveau `FakeLogger<T>` et ensuite établit le `UmamiData` service avec le nom d'utilisateur et le mot de passe que je veux utiliser (sois-ce que je peux tester l'échec

## Les tests utilisant FakeLogger

Puis mes tests peuvent devenir:

```csharp
    [Fact]
    public async Task SetupTest_Good()
    {
        var serviceProvider = GetServiceProvider();
        var authService = serviceProvider.GetRequiredService<AuthService>();
        var authLogger = serviceProvider.GetRequiredService<ILogger<AuthService>>();
        var result = await authService.LoginAsync();
        var fakeLogger = (FakeLogger<AuthService>)authLogger;
        FakeLogCollector collector = fakeLogger.Collector; // Collector allows you to access the captured logs
         IReadOnlyList<FakeLogRecord> logs = collector.GetSnapshot();
         Assert.Contains("Login successful", logs.Select(x => x.Message));
        Assert.True(result);
    }
```

Lorsque vous le voyez, je vais simplement appeler `GetServiceProvider` la méthode pour obtenir mon fournisseur de services, puis obtenir le `AuthService` et `ILogger<AuthService>` du fournisseur de services.

Parce que je les ai établies comme `FakeLogger<T>` Je peux ensuite accéder au `FakeLogCollector` et `FakeLogRecord` pour obtenir les registres et les vérifier.

Puis je peux simplement vérifier les registres pour les messages corrects.

# En conclusion

C'est ainsi qu'il y a il, une façon simple de tester les messages log dans l'unité d'essais sans le nonsens Moq.