تمسخر چیست؟ تمسخر در دات نت توضیح داده شده با مثال
بیایید به سفری برویم تا مفهوم تمسخر را در توسعه نرم افزار دات نت ابهام کنیم. بیایید تحلیل کنیم که تمسخر واقعاً چقدر ساده و در دسترس است. به من بپیوندید تا این موضوع را تحلیل کنیم، همانطور که من پوشش می دهم:
درک تمسخر: چرا برای ایجاد یک استراتژی تست قوی لازم است.
کاوش در برخی از رایج ترین کتابخانه های تمسخر آمیز: مانند Moq، NSubstitute، FakeItEasy، و Rhino Mocks.
تسلط بر تکنیک های تمسخر: با استفاده از هر یک از این کتابخانه ها، شما را مجهز به دانش برای انتخاب بهترین ابزار تمسخر برای نیازهای خود می کند.
هدف از این آموزش این است که به شما دانشی بدهد تا بتوانید تصمیم بگیرید که کدام کتابخانه مسخره را ترجیح می دهید، پس می توانید به جلو بروید و چند تست قدرتمند در برنامه خود بنویسید.
پیش نیازهای این آموزش
آشنایی با برنامه نویسی سی شارپ
آشنایی با C# Unit Testing
یک IDE (Rider، Visual Studio و غیره)، یا ویرایشگر کد (VS Code، Sublime Text، Atom و غیره)
شروع به کار/تنظیم
برای سرعت بخشیدن به فرآیند، من یک مخزن عمومی GitHub را برای این آموزش در دسترس قرار داده ام. میتوانید آن را شبیهسازی کنید و از آن در دستگاه محلی خود برای پیگیری استفاده کنید.
به سادگی به این پیوند بروید و مخزن را در دستگاه محلی خود شبیه سازی کنید.
اگر فراموش کردهاید این کار را انجام دهید، بهروزرسانی سریع: به پیوند بالا بروید و در گوشه سمت راست بالا روی «کد» کلیک کنید و سپس URL ارائه شده را کپی کنید.
پوشه git محلی خود را پیدا کنید، (اگر ندارید، یکی را در پوشه root کاربر خود ایجاد کنید). سپس در ترمینال دلخواه خود به git قدیمی تر بروید و دستور زیر را اجرا کنید.
// (replacing <url> with the url) git clone <url>
مروری کوتاه بر برنامه
راه حلی که به تازگی شبیه سازی کرده اید یک پروژه Web API پایه است که به یک کتابخانه کلاس با برخی از اشیاء و سرویس های دامنه Todo ارجاع می دهد که فهرست ی از موارد todo را تغییر می دهد.
برای هدف این آموزش، این عناصر به جای اتصال به پایگاه داده در یک فهرست در حافظه ذخیره می شوند. اما شما می توانید از یک پایگاه داده یا سایر اشکال روش های ماندگاری داده استفاده کنید.
با این حال، برای هدف این آموزش، ما کمتر نگران تداوم داده ها هستیم و بیشتر در مورد تمسخر این سرویس هستیم.
تمسخر چیست؟
تمسخر در توسعه نرم افزار مفهومی شبیه سازی یک رفتار یا شیء برگشتی از یک کلاس، متد یا سرویس است که بخش دیگری از سیستم تحت آزمایش به آن وابسته است.
هنگام آزمایش یک مؤلفه یا واحد کد خاص، اغلب لازم است که آن را از وابستگیهای آن، مانند پایگاههای داده، سرویسهای وب، یا کلاسهای دیگر جدا کنید تا اطمینان حاصل شود که آزمون صرفاً بر روی عملکرد واحد مورد آزمایش تمرکز میکند. مربوط به خود با جنبه های خارجی کد.
Mocking به توسعه دهندگان این امکان را می دهد که اشیاء ساختگی یا پیاده سازی ساختگی این وابستگی ها را ایجاد کنند که به روشی از پیش تعیین شده رفتار می کنند و رفتار اشیاء واقعی را تقلید می کنند.
با استفاده از اشیا یا روش های مسخره شده، می توانیم ورودی و خروجی وابستگی ها را کنترل کنیم. این امر آزمایش سناریوهای مختلف را آسان تر می کند، جایی که منطق کسب و کار به نتیجه یک وابستگی وابسته است.
مثال
فرض کنید یک نقطه پایانی API داریم که یک مخزن را فرا می خواند که به یک پایگاه داده متصل می شود. نوع پاسخ API ما به مقدار بازگشتی از مخزن بستگی دارد: ما یا یک پاسخ 400 یا 200 را از API خود برمی گردانیم.
ما به سادگی میتوانیم مقدار بازگشتی مخزن را مسخره کنیم و آزمایش کنیم که API ما پاسخ صحیح را در هر دو سناریو بدون نیاز به دست زدن به پایگاه داده ما انجام دهد.
در اصل، تمسخر به توسعهدهندگان کمک میکند تا با جداسازی کد مورد آزمایش و ارائه رفتار قابل پیشبینی برای وابستگیهای آن، تستهای قابل اعتمادتر و کارآمدتری بنویسند و در نتیجه کیفیت کلی نرمافزار را بهبود ببخشند.
مزایای تمسخر چیست؟
جداسازی کد
همانطور که قبلاً توضیح داده ام، وابستگی های تمسخر آمیز امکان جداسازی کد را برای آزمایش فراهم می کند. با مسخره کردن وابستگیها، میتوانید نقاط شکست را در کد مورد آزمایش مشخص کنید، نه خود وابستگیها (مگر اینکه آنها را به اشتباه مسخره کنید - که امیدواریم این آموزش به شما کمک کند از آن اجتناب کنید).
تست سریعتر
با جایگزینی وابستگی های واقعی با پیاده سازی های مسخره شده، آزمایش را می توان سریعتر انجام داد. شما با ناسازگاری ها، نتایج غیرقابل اعتماد یا غیرقابل پیش بینی ناشی از این وابستگی ها مبارزه نمی کنید. این نیاز به راه اندازی و از بین بردن منابع خارجی را که گاهی اوقات می تواند پیچیده و وقت گیر باشد، از بین می برد.
تست قطعی
اشیاء ساختگی یک محیط کنترل شده را ارائه می دهند که به توسعه دهندگان این امکان را می دهد تا رفتار و پاسخ دقیق وابستگی ها را مشخص کنند. این رویکرد به این معنی است که آزمایشها سازگار هستند و یافتن اشکالات و مشکلات اشکالزدایی را آسانتر میکند، بهویژه مواردی که رویکرد TDD (Test Driven Development) را اتخاذ میکنند.
تست موازی
Mocking با حذف وابستگی به منابع خارجی که ممکن است در طول آزمایش محدود یا غیرقابل دسترس باشند، آزمایش موازی را امکان پذیر می کند (آزمون های متعدد به طور همزمان اجرا می شوند).
به عنوان مثال، اگر لایه اتصال پایگاه داده خود را مسخره نمیکردید، تلاش برای اجرای آزمایشها به صورت موازی ممکن است باعث معیارهای ناهماهنگ پاس/شکست شود، زیرا آزمایش دیگری میتواند بر جدول پایگاه دادهای که در آزمایش دیگری استفاده میکنید تأثیر بگذارد. تمسخر این لایه به این معنی است که آزمایشات شما اکنون نسبت به این لایه آگنوستیک هستند و می توانند همزمان اجرا شوند.
کاهش تعمیر و نگهداری تست
از آنجایی که اشیاء ساختگی رفتار وابستگیها را محصور میکنند، تغییرات در آن وابستگیها لزوماً نیازی به بهروزرسانی در خود تستها ندارد. این امر سربار نگهداری مرتبط با پایگاه های کد و وابستگی های در حال تحول را کاهش می دهد.
پوشش تست پیشرفته
Mocking به توسعه دهندگان اجازه می دهد تا طیف گسترده ای از سناریوها و موارد لبه را شبیه سازی کنند. با کنترل رفتار وابستگیها، توسعهدهندگان میتوانند اطمینان حاصل کنند که آزمایشهای آنها همه مسیرهای مربوطه را از طریق کد اعمال میکنند و هرگونه محدودیتهای واقعی یا فیزیکی را حذف میکنند.
چیزهایی که با تمسخر باید از آنها آگاه بود
پیچیدگی: گاهی هنگام تمسخر/آزمایش نواحی پیچیده برنامه، تمسخر نیز می تواند پیچیده شود. با این حال، اگر سیستم برای تمسخر بسیار دشوار است، ممکن است نیاز به ارزیابی مجدد معماری خود داشته باشید.
منحنی یادگیری: به درک نحو و مفاهیم کتابخانه تمسخر آمیز نیاز دارد، که می تواند برای توسعه دهندگانی که تازه وارد تست واحد یا چارچوب خاص هستند چالش برانگیز باشد.
تعیین بیش از حد : تمسخر می تواند منجر به تعیین بیش از حد رفتار کد تحت آزمایش شود. این به این معنی است که آزمایشها ممکن است به شدت با جزئیات پیادهسازی مرتبط شوند و در هنگام تغییر پیادهسازی، آنها را شکننده و مستعد شکستن کنند. ایجاد تعادل بین تأیید رفتار و تمرکز بر نتایج مطلوب ضروری است.
مراقب تستهای مثبت کاذب باشید: در حالی که تمسخر به شما امکان میدهد واحدهای کد را جدا کنید، ممکن است احساس امنیت کاذب ایجاد کند. ماک ها وابستگی ها را شبیه سازی می کنند، اما ممکن است رفتار وابستگی های واقعی را به طور کامل تکرار نکنند. تستهای یکپارچهسازی یا تستهای سرتاسری هنوز برای تایید رفتار سیستم بهعنوان یک کل ضروری هستند.
کتابخانه های محبوب دات نت Mocking
در اینجا چند کتابخانه محبوب تست دات نت آورده شده است:
FakeItEasy
NS جایگزین
Moq
تمسخر کرگدن
اینها فقط فهرستی از پرکاربردترین کتابخانه های مسخره دات نت هستند که به صورت آنلاین در دسترس هستند، اما تعداد بیشتری نیز وجود دارد. من به شدت توصیه می کنم از یکی از اینها استفاده کنید زیرا دارای جامعه بزرگتر، پایگاه کد معتبرتر، و مستندات خوب (حیاتی هنگام شروع کار) هستند.
هر یک از این کتابخانه های تمسخر آمیز نحو خاص خود را برای ساختن تمسخر اشیا دارند، با این حال همه آنها از اصول یکسانی پیروی می کنند.
شی/نوع/سرویسی را که می خواهید مسخره کنید، اعلام کنید
چگونه می خواهید آن شی/نوع/سرویس اجرا شود (پیاده سازی)
مقدار برگشتی چقدر است (در صورت لزوم).
نگاهی به تست ها
اگر راه حل را باز کنید و به پروژه "تست" بروید، می بینید که ما چهار فایل با هر یک از تست های مختلف کتابخانه مسخره در آنجا داریم.
FakeItEasyApiTests.cs
MoqApiTests.cs
NSubstituteApiTests.cs
RhinoMocksApiTests.cs
در داخل این فایل ها خواهید دید که ما چهار تست بسیار اساسی XUnit داریم. من آنها را مختصر و ساده برای هدف این آموزش نگه داشته ام.
فرو رفتن عمیق در ساختار تست
هر فایل آزمایشی از یک سازنده برای مقداردهی اولیه یک نسخه خصوصی از سرویسهای قابل احترام خود استفاده میکند، و میتوانید ببینید که چگونه اینها از کتابخانهای به کتابخانه دیگر متفاوت هستند، اما همچنان مفاهیم یکسانی را دنبال میکنند.
// FakeItEasy _fakeTodoService = A.Fake<ITodoService>(); // NSubstitute _substituteTodoService = Substitute.For<ITodoService>(); // Moq _mockTodoService = new Mock<ITodoService>(); // Rhino Mocks _mockTodoService = MockRepository.GenerateMock<ITodoService>();
انتخاب کتابخانه تمسخرآمیز «درست» همه به ترجیحات شخصی بستگی دارد، و آنچه احساس میکنید نوشتن، کار کردن و خواندن/درک کردن آن آسانتر است.
برخی ممکن است از کلماتی مانند Fake
یا Substitute.For
استفاده کنند. برای درک یا خواندن آسان تر. در حالی که دیگران ممکن است A.Fake
غیر شهودی بدانند و new Mock<type>
واضح تر ترجیح دهند.
ترتیب، عمل و ادعا
با پیروی از اصل تست AAA (ترتیب، عمل و ادعا) میتوانیم تستهای خود را با دقت ساختار دهیم و مشخص کنیم که چه کاری و کجا انجام میدهیم.
رویکرد AAA برای آزمایش شامل سه مرحله است:
ترتیب : محیط آزمایشی، سرویسهای مسخرهشده/وابستگیهای خارجی را تنظیم کنید.
Act : عمل مورد آزمایش را انجام دهید.
ادعا : نتیجه مورد انتظار را تأیید کنید.
استفاده از Mocks برای شبیه سازی آیتم های برگشتی
بیایید نقطه پایانی getAll
(GetAllTodoItems) را با تمسخر متد TodoService.GetAllTodos
برای بازگرداندن فهرست ی از کارها آزمایش کنیم.
این رویکرد نیاز به راهاندازی و ایجاد پایگاه داده برای هر سناریوی آزمایشی را حذف میکند و از آزمایش متمرکز مقادیر برگرداننده نقطه پایانی API در برابر معیارهای خاص اطمینان میدهد.
ماک ها راه حل ایده آلی را ارائه می دهند و به ما امکان می دهند رفتار مورد نظر را بدون دخالت سایر تست ها شبیه سازی کنیم.
ما می توانیم این کار را انجام دهیم (به یاد داشته باشید که کد کامل در مخزن موجود است):
// FakeItEasy A.CallTo(() => _fakeTodoService.GetAllTodos()).Returns(expectedTodos); // NSubstitute _substituteTodoService.GetAllTodos().Returns(expectedTodos); // Moq _moqTodoService.Setup(s => s.GetAllTodos()).Returns(expectedTodos); // Rhino Mocks _mockTodoService.Stub(s => s.GetAllTodos()).Return(expectedTodos);
این روش ها چه می کنند؟
ویژگی مشترکی که در اکثر کتابخانه ها خواهید دید، استفاده از توابع لامبدا برای تعیین اینکه کدام روش مورد تمسخر قرار می گیرد است.
تابع لامبدا ارائه شده در روش راه اندازی اساساً یک مرحله پیکربندی است که مشخص می کند در هنگام فراخوانی روش مسخره شده چه اقدامی باید انجام شود. این پیکربندی زمانی که روش مسخره شده در طول آزمایش فراخوانی می شود ذخیره و اعمال می شود.
بیایید آن را تجزیه کنیم، آنچه که ما انجام می دهیم:
لامبدا مشخص می کند که کدام روش در سرویس مسخره شده را قصد داریم پیکربندی/تنظیم کنیم.
لامبدای که ما از آن عبور میکنیم بلافاصله با روش راهاندازی اجرا نمیشود. ما به آزمون نمی گوییم که روش را فوراً اجرا کند. ما می گوییم، "این دستورالعمل/تنظیم را برای زمانی که متد واقعی در طول تست فراخوانی می شود، به خاطر بسپارید."
هنگامی که روشی که ما مسخره می کنیم در طول آزمایش فراخوانی می شود، تحلیل می کند که آیا امضای تماس با پیکربندی تنظیمی که ما ارائه کرده ایم مطابقت دارد یا خیر. اگر مطابقت داشته باشد، آزمایش از دستورالعملهای داده شده در هنگام راهاندازی پیروی میکند.
یادداشت های مهم:
از طرف دیگر، NSubstitute به توسعه دهنده اجازه می دهد تا روش را مستقیماً روی شی جعلی مسخره کند. این بدان معنی است که شما می توانید به روش جعلی GetAllTodos
دسترسی داشته باشید و به سادگی مقدار بازگشتی را به مقدار مورد انتظار خود تنظیم کنید.
اگرچه Moq از یک روش Setup استفاده می کند، اما تا حدی با روش های دیگر تفاوت دارد. Moq به صورت داخلی یک شی پراکسی ایجاد می کند که نشان دهنده شی مورد تمسخر است و یک ویژگی .Object
را برای دسترسی به آن در معرض نمایش می گذارد. در قسمت بعدی خواهیم دید که این چگونه کار می کند.
نحوه تماس با سیستم تحت آزمایش (SUT)
// FakeItEasy var sut = new TodoController(_fakeTodoService); // NSubstitute var sut = new TodoController(_substituteTodoService); // Moq -- slightly different to the others var sut = new TodoController(_moqTodoService.Object); // Rhino Mocks var sut = new TodoController(_mockTodoService);
در سه کتابخانه از چهار کتابخانه، می توانید شی مسخره شده را مستقیماً منتقل کنید. با این حال، Moq برای استفاده از آن نیاز به دسترسی به ویژگی .Object
روی ماک دارد. پس ، moqTodoService.Object
به عنوان یک آرگومان به کنترلر ارسال کردیم.
با اجرای تست ها، می توانید ببینید که همه آنها موفق می شوند. اگر هر کدام از کدهای موجود در مخزن را تغییر دهید، هیچ تفاوتی نخواهد داشت زیرا مخزن در این تست ها مورد تمسخر قرار می گیرد. سعی کنید عملکرد مخزن را تغییر دهید و تست ها را دوباره اجرا کنید، آنها به موفقیت ادامه می دهند.
ما روی عملکرد نقطه پایانی تمرکز می کنیم، نه آنچه که مخزن مسخره شده انجام می دهد، و این زیبایی تمسخر است.
گزینه های با تمسخر بی پایان هستند
مسخره کردن فقط به ما اجازه نمی دهد آنچه را که از یک شی مسخره شده بازگردانده می شود تنظیم کنیم، بلکه می تواند به ما اجازه دهد پیاده سازی را مسخره کنیم، از جمله توانایی ایجاد خطاهای خاص تا بتوانیم مدیریت خطای API و مسیرهای ناخوشایند را نیز آزمایش کنیم.
این در آزمون Delete_Returns500_AndErrorMessageThrown_WhenExceptionThrown
در هر فایل آزمایشی کتابخانه نشان داده شده است.
// FakeItEasy A.CallTo(() => _fakeTodoService.Delete(1)).Throws(new Exception(errorMessage)); // NSubstitute _substituteTodoService.When(x => x.Delete(1)).Do(x => throw new Exception(errorMessage)); // Moq _moqTodoService.Setup(s => s.Delete(1)).Throws(new Exception(errorMessage)); // Rhino Mocks _mockTodoService.Stub(s => s.Delete(1)).Throw(new Exception(errorMessage));
با استفاده از کتابخانههای مختلف، میتوانیم متد Delete
را در سرویس هر استثنایی که میخواهیم ایجاد کنیم. این برای زمانی ایده آل است که می خواهید کدهای وضعیت مختلف را برگردانید، یا بسته به نوع استثنای پرتاب شده، خطاها را به روش های مختلف مدیریت کنید.
به عنوان مثال می توانیم Throws(new Exception(errorMessage)
به Throws(new UnauthorizedAccessException()
تغییر دهیم و تحلیل کنیم که آیا کد وضعیت 401 هنگام پرتاب برگردانده می شود.
راه اندازی جهانی
می توانید چندین پیکربندی را به یک روش اختصاص دهید. این در شرایطی که میخواهید تمام تنظیمات شی مورد تمسخر را در یک مکان تنظیم کنید عالی است. به عنوان مثال، در سازنده کلاس تست.
در برخی از چارچوبهای آزمایشی (مانند NUnit) میتوانید از ویژگی [OneTimeSetUp]
در بالای متد خود استفاده کنید که قبل از موارد آزمایشی شما اجرا میشود، یا به سادگی از سازنده کلاس آزمایشی خود استفاده کنید.
در این سناریو می توانید کاری انجام دهید (در Moq) مانند:
public MoqApiTests() { _mockTodoService = new Mock<ITodoService>(); _mockTodoService.Setup(x => x.Delete(1)).Throws(new Exception("This is a generic exception")); _mockTodoService.Setup(x => x.Delete(2)).Throws(new UnauthorizedAccessException("You cannot perform this action on this item")); }
در این مثال، ما راهاندازی فراخوانهای سرویس مسخرهشده را با آرگومانهای مختلف به یک روش نشان میدهیم که هر کدام باعث ایجاد استثناهای متفاوتی میشوند.
این رویکرد برای آزمایش نتایج مختلف هنگامی که استثناهای مختلف در تستهای جداگانه رخ میدهند، بدون اینکه کد آزمایشی ما را با تنظیمات تکراری درهمریزی کنیم، مفید است.
مثلا:
// Test 1 var result = TodoController.Delete(1); // Assert handles general exception // Test 2 var result = TodoController.Delete(2); // Assert handles UnauthorizedAccessException
من ترجیح میدهم برای اطمینان از اینکه هیچ عامل خارجی روی ماک تأثیر نمیگذارد، ماکهایی را در هر آزمون جداگانه تنظیم کنم.
به این ترتیب، من به راحتی میتوانم آنچه را که در تست مورد تمسخر قرار میگیرد، بدون جستجوی شیء مسخرهشده و راهاندازی در جای دیگر شناسایی کنم.
چه می شود اگر برایم مهم نباشد که در چه چیزی هستم؟
در نمونه های حذف خود، ما به طور مداوم یک شناسه به پیاده سازی ساختگی ارسال کردیم. در نتیجه، اگر از طریق فراخوانی TodoController.DeleteTodoItem
، متد را با شناسه دیگری مانند 101
فراخوانی کنیم، نتیجه مشابهی دریافت نمیکنیم.
این به این دلیل است که ما به صراحت به شیء مسخره شده دستور دادیم تا زمانی که متد stubbed با شناسه 1 فراخوانی می شود، خطا ایجاد کند.
برای پرداختن به این موضوع، می توانیم کمتر دقیق باشیم. هر کتابخانه سینتکس مخصوص به خود را برای این کار دارد، به ما این امکان را می دهد که مشخص کنیم اگر هر عدد صحیحی به متد ارسال شود، استثنای خاصی را ایجاد می کند.
// FakeItEasy A.CallTo(() => _fakeTodoService.Delete(A<int>._)).Throws( new Exception(errorMessage)); // NSubstitute _substituteTodoService.When(x => x.Delete(Arg.Any<int>())).Do(x => throw new Exception(errorMessage)); // Moq _mockTodoService.Setup(s => s.Delete(It.IsAny<int>())).Throws(new Exception(errorMessage)); // Rhino Mocks _mockTodoService.Stub(s => s.Delete(Arg<int>.Is.Anything)).Throw(new Exception(errorMessage));
این کد نشان می دهد که وقتی هر آرگومان از نوع int
ارسال می شود، باید این استثنا را پرتاب کند.
NSubstitute در نحو کمی متفاوت است: برای پرتاب خطای مشخص شده هنگام مواجهه با این سناریو، بر خلاف زمانی که به آن اطلاع میدادند که یک شی را برگرداند، به دستورالعمل صریح نیاز دارد. این تفاوت ناشی از مکانیسم های درونی کتابخانه است.
ادعای تمسخر نامیده می شود
در برخی موارد، ممکن است بخواهید تحلیل کنید که سرویس مسخره شده با آرگومان های صحیح فراخوانی شده است. این به ویژه در هنگام برخورد با یک سرویس "آتش و فراموش کردن" مفید است.
در این سناریو، نقطه پایانی API شما فراخوانی میشود، و در حالی که همیشه true را برمیگرداند، سرویسی را برای انجام برخی اقدامات به طور مستقل فعال میکند، که بر نوع بازگشت API تأثیری نمیگذارد (شاید یک سرویس اعلان ناهمزمان).
این یکی از معدود مواردی است که ممکن است بخواهید برای اطمینان از فراخوانی سرویس "آتش و فراموش کردن" خود، یک تحلیل سریع عقلانی انجام دهید (اگرچه در حالت ایده آل، یک آزمایش یکپارچه سازی با آن سرویس انجام می دهید).
اگر به نقطه پایانی DeleteTodoItem
و تست DeleteAPI_CallsNotificationService_WithTaskId_AndUserId
در هر فایل آزمایشی نگاهی بیندازید، می توانید نمونه های کاملی از نحوه انجام این کار را مشاهده کنید.
ما تأیید میکنیم که وقتی DeleteTodoItem
فرا میخوانیم، در مسیر خوشحالیمان، NotificationService.NotifyUserTaskCompleted
با شناسه مورد برای حذف، و شناسه کاربر با کد سخت فراخوانی میشود.
به عنوان تمرین، میتوانید یک سرویس کاربری ایجاد کنید که شناسه کاربر وارد شده را برمیگرداند، و از آن میتوان برای ارسال شناسه به سرویس استفاده کرد. این را نیز می توان در آزمون مورد تمسخر قرار داد.
// FakeItEasy A.CallTo(() => _fakeNotificationService.NotifyUserTaskCompleted(1,1)).MustHaveHappened(1, Times.Exactly); // NSubstitute _notificationService.Received().NotifyUserTaskCompleted(1,1); // Moq _moqNotificationService.Verify(x => x.NotifyUserTaskCompleted(1,1)); // Defaults to Times.AtLeastOnce // Rhino Mock _mockNotificationService.AssertWasCalled(x=>x.NotifyUserTaskCompleted(1,1));
نتیجه
در نتیجه، تطبیق پذیری اشیاء مسخره شده کاربردهای بی شماری را ارائه می دهد که در آزمایش واحدهای کد جداگانه ضروری است.
در حالی که من چندین عملکرد و اعتبار سنجی قابل دستیابی با ساختگی ها را پوشش داده ام، موارد بیشتری مانند ترتیب فراخوانی روش و اعتبارسنجی منفی وجود دارد.
به نظر من، انتخاب یک کتابخانه تمسخر آمیز برای یک پروژه ذهنی است، بدون هیچ گزینه قطعی درست یا غلط. در حالی که برخی از کتابخانهها ممکن است پسوندهای راحتتر یا نحو واضحتری ارائه دهند، تصمیم در نهایت به ترجیحات شخصی خلاصه میشود.
امیدوارم که این آموزش نگاهی اجمالی به دنیای تمسخر برای شما داشته باشد و تفاوت های نحوی در کتابخانه های مختلف را روشن کند.
مثل همیشه، از تماس با ما دریغ نکنید (لینک ها در بیو).
ارسال نظر