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

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Core xUnit

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

Wednesday, 04 September 2024

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.

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.

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

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 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.

    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:

    [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.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.