اختبار وحدة Umami.Net - التسجيل في ASPM SK2NET Core
المقدمة
أنا 'أنا نُوِب نسبي يستعمل موك (نعم أنا ♫' ♫أنا أدرك المناقشات ♫ ) ♫ وكنت أحاول اختبار خدمة جديدة أنا ♪ ' ♫ أضيف إلى أومامي ♪. ♫ شبكة ♪
المشكلة
كنت أحاول أن أضيف اختباراً بسيطاً للصفة الإتصالية التي أريد أن أستخدمها عندما أسحب البيانات.
كما ترون، ' هو خدمة بسيطة تنقل اسم пользователя وكلمة مرور إلى /api/auth/login نقطة النهاية وتحصل على النتيجة. إذا كان النتيجة ناجحة فإنه يحفظ الرموز في _token و يضع الحقل Authorization عنوان لـ HttpClient لتستخدم في الطلبات المستقبلية.
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;
}
}
الآن أردت أيضا أن أختبر ضد المسجل للتأكد من أنه يسجل الرسائل الصحيحة Microsoft.Extensions.Logging و أردت أن أختبر أن رسائل الملاحظات الصحيحة كانت تُكتب إلى الملاحظ
في موك هناك ' مجموعة من المدونات حول اختبار السجل لديهم جميعهم هذا الشكل الأساسي ( من "https"
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;
}
على الرغم من تغيرات "Moq" و ' مؤخراً، ( "It" "MSC2" "IsAnyType" قديمة الآن "M SK3" "ASP" . "NET Core" ' تغييرات "FormattedLogValues" كان لدي الكثير من الوقت لجعل هذا يعمل"
حاولت مجموعة من الإصدارات والمتغيرات لكنها دائماً فشلت
الحل
لذا فقراءة مجموعة من رسائل GitHub صادفت رسالة من ديفيد فوولر (زميلي السابق والآن رب .NET) التي أظهرت طريقة بسيطة لاختبار السجل في ASP
هذا يستخدم جديد بالنسبة لي Microsoft.Extensions.Diagnostics.Testing حزمة الذي يحتوي على بعض الإضافات المفيدة حقاً لاختبار السجل
فبدلاً من كل الأشياء الموكية قمت بإضافة Microsoft.Extensions.Diagnostics.Testing و أضافت التالي إلى إختباراتي.
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();
}
ستلاحظون أن هذا يضع مجموع خدماتي FakeLogger<T> ومن ثم يقوم بإعداد UmamiData خدمة مع username وパスワード أريد أن أستخدم (لذلك أستطيع إختبار الفشل).
الإختبارات باستخدام FakeLogger
ثم يمكن لاختباراتي أن تصبح :
[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);
}
حيث سترى ' سأتصل ببساطة GetServiceProvider طريقة للحصول على مزود خدماتي, ثم الحصول على AuthService و ILogger<AuthService> من مقدم الخدمة.
لأنني وضعت هذه كـ FakeLogger<T> ومن ثم يمكنني الوصول إلى FakeLogCollector و FakeLogRecord للحصول على الملاحظات والتحقق منها.
عندها أستطيع ببساطة فحص الملاحظات للرسال الصحيحة.
في الختام
إذاً هناك لديكه, طريقة بسيطة لاختبار رسائل الملاحظات في إختبارات وحدة بدون مزخرفة Moq.