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
Yksikön testaus Umami.Net - ASP:n Logging in .NET Core
Wednesday, 04 September 2024
Esitys
I'niin suhteellinen noob, joka käyttää Moq-järjestelmää (kyllä I 'nii tietoinen ristiriitaisuuksistaM SK3 ja pyrin testaamaan uutta palvelua I'niitän UmamiinMST5NetMSV6UmamiDataMSP7 Tämä on palvelu, jonka avulla voin vetää tietoja omalta Umami instancelta, jota voin käyttää asioissa kuten populariteetin ja muiden vastaavien mainintojen sortoinnissa.
Ongelma
Yritin lisätä yksinkertaisen testin, joka koskee sitä login-toimintoa, jota minun on käytettävä tietojen vetämisessä.
Kuten voitte nähdä, ' on yksinkertainen palvelu, joka siirtää käyttäjänamen ja -passin /api/auth/login loppupiste ja saa tuloksen. Jos tulos on onnistunut, se tallentaa token _token ja asettaa Authorization otsikko HttpClient käytettäviksi tulevissa pyyntöissä.
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;
}
}
Nyt halusin myös testata logaria sen varmistamiseksi, että se kirjaa oikeat viestit. IM SK1m käyttäen Microsoft.Extensions.Logging namespace ja halusin testata, että oikeat logiviestit kirjoitetaan logiin.
Moqissa on ”'”-osoitteita, jotka koskevat testausloggingia, ja niillä kaikilla on tämä perusmuoto: ( https://://adamstorr .co.uk/blogMST6mockingMst7iloggerM st8withMSt9moqMrst10
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;
}
Mutta Moq:n viimeaikaisten muutosten vuoksi (, It, . ja IsAnyType ovat nyt vanhentuneita.
Olen yrittänyt monenlaisia versioita, mutta ne ovat aina epäonnistuneet.
Ratkaisu
Näin ollen lukiessani joitakin GitHubin viestejä törmäsin David Fowlerin postiin ( entisestä kollegastani ja nyt Lord of .NET), jossa esitettiin yksinkertainen tapa testata ASP:n tilaamista.
Siinä käytetään uusi minulle Microsoft.Extensions.Diagnostics.Testing paketti , jolla on joitakin todella hyödyllisiä lisäyksiä logauksen testaamiseksi.
Sen sijaan, että lisäisin kaikki Moq-asiat Microsoft.Extensions.Diagnostics.Testing ja lisättiin seuraavat testini kohtaan.
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();
}
Huomaatte, että tämä asettaa palveluniCollectionin. FakeLogger<T> ja sen jälkeen perustaa UmamiData palvelu, johon sisältyy käyttäjänimi ja -tunnus, jota haluan käyttää (niten voin testata epäonnistumisen
Testit FakeLoggerin avulla
Silloin testini voivat olla:
[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);
}
Kun näette, kutsun yksinkertaisesti GetServiceProvider menetelmä saada palveluntarjoajaani, ja sitten saada AuthService ja ILogger<AuthService> palveluntarjoajalta.
Koska minulla on nämä järjestelmät FakeLogger<T> Voin sitten käyttää FakeLogCollector ja FakeLogRecord saada pöytäkirjat ja tarkistaa ne.
Sen jälkeen voin vain tarkistaa pöytäkirjat oikeista viesteistä.
Päätelmissä
Näin ollen teillä on se, yksinkertainen tapa testata pöytäkirjan viestejä yksiköiden testeissä Moq-järjettömyyden välttämättömällä tavalla