اختبارات C#: الوحدة والتكامل والنهاية إلى النهاية — المستوى المتقدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا كتابة الاختبارات على المستوى المتقدم؟

المستوى المبتدئ من الاختبارات في C# يقتصر عادةً على Assert.Equal البسيطة واختبارات الوحدة المنعزلة. ومع ذلك، في مشاريع المؤسسات الحقيقية، هذا غير كافٍ. غالبًا ما تظهر الأخطاء عند تقاطع المكونات — أثناء التفاعل مع قاعدة البيانات، أو واجهات برمجة التطبيقات الخارجية، أو في منطق الأعمال المعقد ذي الآثار الجانبية.

الاختبار المتقدم في C# (.NET) هو القدرة على بناء هرم اختبارات، حيث تكون اختبارات الوحدة سريعة ومنعزلة، وتتحقق اختبارات التكامل من التفاعلات الحقيقية، وتحاكي اختبارات E2E سلوك المستخدم. في هذه المقالة، سنستعرض الأدوات الحديثة: xUnit، و Moq، و FluentAssertions، و Testcontainers، و WebApplicationFactory. ستتعلم كيفية كتابة اختبارات موثوقة لا تنكسر عند إعادة الهيكلة وتمنحك الثقة في الكود.



1. اختبارات الوحدة المتقدمة: الكائنات الوهمية (Mocks) وكائنات البديل (Stubs)

يجب أن تكون اختبارات الوحدة معزولة عن التبعيات الخارجية. على المستوى المتقدم، نستخدم مكتبات لإنشاء كائنات وهمية (mock-objects)، مثل Moq أو NSubstitute.



الإعداد الصحيح للكائنات الوهمية (Mock-objects)

بدلاً من إنشاء البدائل يدويًا، استخدم Mock.Of<T>() للإعداد السريع. مثال باستخدام Moq و FluentAssertions:

public interface IEmailService{    Task SendAsync(string to, string subject);}

public class NotificationService{ private readonly IEmailService _emailService;

public NotificationService(IEmailService emailService) { _emailService = emailService; }

public async Task NotifyUserAsync(string email) { await _emailService.SendAsync(email, "Welcome!"); }}

// اختبار[Fact]public async Task NotifyUserAsync_ShouldSendEmail(){ // ترتيب var mockEmailService = new Mock<IEmailService>(); var service = new NotificationService(mockEmailService.Object);

// تنفيذ await service.NotifyUserAsync("test@example.com");

// تأكيد mockEmailService.Verify( x => x.SendAsync("test@example.com", "Welcome!"), Times.Once);}


تجنب اختبار تفاصيل التنفيذ

النهج المتقدم هو اختبار السلوك، وليس الاستدعاءات الداخلية. استخدم Verify فقط للتبعيات الحرجة. بالنسبة للباقي، تحقق من النتيجة.



2. اختبارات التكامل: قاعدة البيانات والخدمات الخارجية

تتحقق اختبارات التكامل من أن عدة وحدات تعمل معًا. بالنسبة لـ .NET Core/5+، الأداة المثالية هي WebApplicationFactory (لـ ASP.NET Core) و Testcontainers (لحاويات التبعيات).



إعداد WebApplicationFactory مع قاعدة بيانات حقيقية

بدلاً من استخدام موفر InMemory (الذي يتصرف بشكل مختلف عن قاعدة البيانات الحقيقية)، استخدم Testcontainers لتشغيل PostgreSQL أو SQL Server في Docker:

public class IntegrationTestFixture : IAsyncLifetime{    private readonly TestcontainersContainer _dbContainer;

public string ConnectionString { get; private set; }

public IntegrationTestFixture() { _dbContainer = new TestcontainersBuilder<TestcontainersContainer>() .WithImage("postgres:15") .WithPortBinding(5432, true) .WithEnvironment("POSTGRES_USER", "test") .WithEnvironment("POSTGRES_PASSWORD", "test") .WithEnvironment("POSTGRES_DB", "testdb") .Build(); }

public async Task InitializeAsync() { await _dbContainer.StartAsync(); ConnectionString = $"Host=localhost;Port={_dbContainer.GetMappedPublicPort(5432)};" + $"Database=testdb;Username=test;Password=test"; }

public async Task DisposeAsync() { await _dbConta

المدونات

توصيات الكتب