In this episode, Robert is joined by Mads Kristensen, who shows us the Web Extension Pack. This extension installs a number of extensions that help you become a more productive Web developer. The extensions contained in the Web Extension Pack have been proven to be stable over time and useful for all Web developers.
اشتراکها
یکی از مشخصات آزمونهای واحد، عدم خروج از مرزهای IO سیستم، در حین اجرای آنها است و چون درهنگام کار با بانکهای اطلاعاتی حتما از مرزهای IO سیستم رد خواهیم شد (کار با شبکه، کار با فایل سیستم، برای به روز رسانی و درج اطلاعات)، نوشتن آزمونهای واحد واقعی، برای برنامههایی که از ORMها استفاده میکنند مشکل است. به همین جهت مباحث mocking، تقلید قسمتهای مختلف ORMها و جایگزین کردن آنها با نمونههای درون حافظهای بسیار مرسوم است. برای رفع این مشکلات، تیم EF Core، یک تامین کنندهی بانک اطلاعاتی ویژهی «درون حافظهای» را به نام «Entity Framework Core InMemory provider» ارائه دادهاست. به این ترتیب، این محل ذخیره سازی اطلاعات درون حافظهای، مشکل رد شدن از مرزهای IO سیستم را برطرف کرده و عملا نیاز به کار کردن با فریم ورکهای mocking را منتفی میکند (حداقل برای تقلید قسمتهای مختلف EF Core).
در این قسمت ابتدا نحوهی فعال سازی فریم ورک آزمونهای واحد مایکروسافت و سپس نحوهی فعال سازی این تامین کنندهی بانک اطلاعاتی درون حافظهای را بررسی خواهیم کرد. به علاوه برای سرویس بلاگهای قسمت قبل نیز آزمون واحد خواهیم نوشت.
نحوهی فعالسازی فریم ورک MSTest در یک پروژهی Class library از نوع NET Core.
تنها نکتهی مهم فعالسازی MSTest در یک پروژهی Class library جدید که برای نوشتن آزمونهای واحد مورد استفاده قرار خواهیم داد، تنظیمات فایل project.json آن است که در ذیل آمده است:
- در اینجا قید testRunner الزامی است؛ در غیراینصورت آزمونهای واحد شما شناسایی نخواهند شد. همچنین بستههای dotnet-test-mstest و MSTest.TestFramework نیز باید اضافه شوند.
- به علاوه در اینجا ارجاعاتی را به اسمبلیهای موجودیتها، Services و DataLayer که در قسمت «شروع به کار با EF Core 1.0 - قسمت 14 - لایه بندی و تزریق وابستگیها» بررسی شدند نیز ملاحظه میکنید.
- همچنین وابستگی جدید Microsoft.EntityFrameworkCore.InMemory نیز در اینجا قابل ملاحظه است. این وابستگی را تنها به پروژهی آزمونهای واحد خود اضافه میکنیم. از این جهت که تنظیمات آن صرفا در این قسمت جدید قید میشوند و نه در سایر قسمتهای برنامه.
پس از آن، کار با این فریم ورک، همانند سایر نگارشهای دات نت خواهد بود:
ابتدا کلاس مدنظر، با ویژگی TestClass مزین میشود. سپس متد آزمون واحد نوشته شده نیز باید به صورت public void و مزین شدهی با ویژگی TestMethod، ارائه شود.
پس از نوشتن اولین آزمون واحد، یکبار پروژه را build کرده و سپس از منوی Test، گزینهی Windows را انتخاب کرده و در اینجا گزینهی Test Explorer را انتخاب کنید. اندکی صبر کنید تا آزمونهای واحد شما شناسایی شوند و سپس گزینهی Run All را انتخاب کنید:
تغییرات Context برنامه جهت استفادهی از تامین کنندهی داخل حافظهای
در مورد نحوهی تعریف و افزودن وابستگیهای EF Core در مطلب «شروع به کار با EF Core 1.0 - قسمت 1 - برپایی تنظیمات اولیه» پیشتر بحث شد و همچنین در مطلب «شروع به کار با EF Core 1.0 - قسمت 3 - انتقال مهاجرتها به یک اسمبلی دیگر»، اطلاعات Context برنامه را به اسمبلی دیگری منتقل کردیم.
اگر از روش بازنویسی متد OnConfiguring برای تنظیم تامین کنندهی بانک اطلاعاتی مورد نظر استفاده میکنید، متد OnConfiguring کلاس Context برنامه چنین شکلی را پیدا میکند:
در اینجا دو تغییر جدید قابل ملاحظه هستند:
الف) اضافه شدن سازندهی دومی که <DbContextOptions<ApplicationDbContext را دریافت میکند. از آن در سمت کدهای آزمون واحد برنامه جهت ثبت ()options.UseInMemoryDatabase استفاده میشود.
ب) به متد OnConfiguring، بررسی optionsBuilder.IsConfigured هم اضافه شدهاست. چون در سمت کدهای آزمون واحد، تامین کنندهی بانک اطلاعاتی درون حافظهای اضافه میشود، مقدار optionsBuilder.IsConfigured به true تنظیم خواهد شد و دیگر از تامین کنندهی SQL Server استفاده نمیشود.
اگر از متد OnConfiguring به این شکل استفاده نمیکنید، تنها ذکر سازندهی دوم ضروری است. از این جهت که در آزمونهای واحد، از تنظیمات متد ConfigureServices کلاس آغازین برنامه استفاده نخواهد شد.
نوشتن آزمونهای واحد مخصوص EF Core
پس از برپایی پیشنیازهای نوشتن آزمونها واحد، شامل تنظیمات فریم ورک MSTest و همچنین افزودن وابستگیهای مرتبط با فایل project.json ایی که در ابتدای بحث عنوان شد و اصلاح سازنده و متد OnConfiguring کلاس Context برنامه جهت آماده سازی آنها برای پذیرش تامین کنندههای دیگر، اکنون یک نمونه از آزمونهای واحد درون حافظهای EF Core، چنین شکلی را خواهد داشت:
توضیحات:
همانطور که در قسمت «تغییرات Context برنامه جهت استفادهی از تامین کنندهی داخل حافظهای» فوق عنوان شد، در حین انجام آزمونهای واحد، دیگر به کلاس آغازین برنامه و تنظیمات آن مراجعه نمیشود. بنابراین باید شبیه به عملکرد متد ConfigureServices آنرا در اینجا پیاده سازی کرد. نمونهای از انجام اینکار را در سازندهی کلاس انجام آزمونهای واحد مشاهده میکنید:
در اینجا است که توسط متد AddEntityFrameworkInMemoryDatabase، کار افزودن تامین کنندهی بانک اطلاعاتی درون حافظهای انجام شده و سپس Context برنامه نیز از آن مطلع میشود (علت افزودن سازندهی دومی که <DbContextOptions<ApplicationDbContext را دریافت میکند).
سپس همانند قبل، باید تمام سرویسهای مدنظر تنظیم شوند تا بتوان از آنها استفاده کرد.
نکتهی مهم دیگری را که باید به آن دقت داشت، ایجاد scope و سپس دسترسی به سرویسها از طریق این Scope است. از این جهت که چون خارج از طول عمر یک درخواست وب قرار داریم، دیگر Scopeها برای ما به صورت خودکار ایجاد و تخریب نمیشوند و باید همانکاری را که ASP.NET Core در پشت صحنه انجام میدهد، به صورت دستی پیاده سازی کنیم:
اگر اینکار صورت نگیرد، چون Scope ایی ایجاد و تخریب نمیشود، کار کردن با متد serviceProvider.GetRequiredService_ اشتباه بوده و همیشه یک وهله از Context را باز میگرداند که مدنظر ما نیست. شبیه به این نکته را در قسمت «مقدار دهی اولیهی جداول بانکهای اطلاعاتی در EF Core» پیشتر ملاحظه کردهاید.
یک نکتهی تکمیلی
EF Core به همراه تامین کنندهی بانک اطلاعاتی SQLite نیز هست. یکی از نکات ویژهی بانک اطلاعاتی SQLite، امکان تنظیم پارامتری است در رشتهی اتصالی آن، که آنرا نیز تبدیل به یک «بانک اطلاعاتی درون حافظهای» میکند. این روش سالها است که جهت انجام آزمونهای واحد ORMها مورد استفاده قرار میگیرد. بنابراین میتوان آنرا به عنوان جایگزینی برای مطلب جاری نیز درنظر گرفت.
اهمیت آن در اینجا است که تامین کنندهی بانک اطلاعاتی درون حافظهای EF، قیود را اعمال نمیکند ؛ اما بانک اطلاعاتی درون حافظهای SQLite واقعا همانند یک بانک اطلاعاتی رابطهای کامل عمل میکند.
در این قسمت ابتدا نحوهی فعال سازی فریم ورک آزمونهای واحد مایکروسافت و سپس نحوهی فعال سازی این تامین کنندهی بانک اطلاعاتی درون حافظهای را بررسی خواهیم کرد. به علاوه برای سرویس بلاگهای قسمت قبل نیز آزمون واحد خواهیم نوشت.
نحوهی فعالسازی فریم ورک MSTest در یک پروژهی Class library از نوع NET Core.
تنها نکتهی مهم فعالسازی MSTest در یک پروژهی Class library جدید که برای نوشتن آزمونهای واحد مورد استفاده قرار خواهیم داد، تنظیمات فایل project.json آن است که در ذیل آمده است:
{ "version": "1.0.0-*", "testRunner": "mstest", "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0" }, "dotnet-test-mstest": "1.1.1-preview", "MSTest.TestFramework": "1.0.1-preview", "NETStandard.Library": "1.6.0", "Microsoft.EntityFrameworkCore": "1.0.0", "Microsoft.EntityFrameworkCore.InMemory": "1.0.0", "Core1RtmEmptyTest.DataLayer": "1.0.0-*", "Core1RtmEmptyTest.Entities": "1.0.0-*", "Core1RtmEmptyTest.Services": "1.0.0-*", "Core1RtmEmptyTest.ViewModels": "1.0.0-*" }, "frameworks": { "netcoreapp1.0": { "imports": [ "dnxcore50", "portable-net45+win8" ] } } }
- به علاوه در اینجا ارجاعاتی را به اسمبلیهای موجودیتها، Services و DataLayer که در قسمت «شروع به کار با EF Core 1.0 - قسمت 14 - لایه بندی و تزریق وابستگیها» بررسی شدند نیز ملاحظه میکنید.
- همچنین وابستگی جدید Microsoft.EntityFrameworkCore.InMemory نیز در اینجا قابل ملاحظه است. این وابستگی را تنها به پروژهی آزمونهای واحد خود اضافه میکنیم. از این جهت که تنظیمات آن صرفا در این قسمت جدید قید میشوند و نه در سایر قسمتهای برنامه.
پس از آن، کار با این فریم ورک، همانند سایر نگارشهای دات نت خواهد بود:
using Microsoft.VisualStudio.TestTools.UnitTesting; namespace EFCore.MsTests { [TestClass] public class CoreTests { [TestMethod] public void Test1() { Assert.IsTrue(true); } } }
پس از نوشتن اولین آزمون واحد، یکبار پروژه را build کرده و سپس از منوی Test، گزینهی Windows را انتخاب کرده و در اینجا گزینهی Test Explorer را انتخاب کنید. اندکی صبر کنید تا آزمونهای واحد شما شناسایی شوند و سپس گزینهی Run All را انتخاب کنید:
تغییرات Context برنامه جهت استفادهی از تامین کنندهی داخل حافظهای
در مورد نحوهی تعریف و افزودن وابستگیهای EF Core در مطلب «شروع به کار با EF Core 1.0 - قسمت 1 - برپایی تنظیمات اولیه» پیشتر بحث شد و همچنین در مطلب «شروع به کار با EF Core 1.0 - قسمت 3 - انتقال مهاجرتها به یک اسمبلی دیگر»، اطلاعات Context برنامه را به اسمبلی دیگری منتقل کردیم.
اگر از روش بازنویسی متد OnConfiguring برای تنظیم تامین کنندهی بانک اطلاعاتی مورد نظر استفاده میکنید، متد OnConfiguring کلاس Context برنامه چنین شکلی را پیدا میکند:
public class ApplicationDbContext : DbContext, IUnitOfWork { private readonly IConfigurationRoot _configuration; public ApplicationDbContext(IConfigurationRoot configuration) { _configuration = configuration; } public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer( _configuration["ConnectionStrings:ApplicationDbContextConnection"] , serverDbContextOptionsBuilder => { var minutes = (int)TimeSpan.FromMinutes(3).TotalSeconds; serverDbContextOptionsBuilder.CommandTimeout(minutes); }); } }
الف) اضافه شدن سازندهی دومی که <DbContextOptions<ApplicationDbContext را دریافت میکند. از آن در سمت کدهای آزمون واحد برنامه جهت ثبت ()options.UseInMemoryDatabase استفاده میشود.
ب) به متد OnConfiguring، بررسی optionsBuilder.IsConfigured هم اضافه شدهاست. چون در سمت کدهای آزمون واحد، تامین کنندهی بانک اطلاعاتی درون حافظهای اضافه میشود، مقدار optionsBuilder.IsConfigured به true تنظیم خواهد شد و دیگر از تامین کنندهی SQL Server استفاده نمیشود.
اگر از متد OnConfiguring به این شکل استفاده نمیکنید، تنها ذکر سازندهی دوم ضروری است. از این جهت که در آزمونهای واحد، از تنظیمات متد ConfigureServices کلاس آغازین برنامه استفاده نخواهد شد.
نوشتن آزمونهای واحد مخصوص EF Core
پس از برپایی پیشنیازهای نوشتن آزمونها واحد، شامل تنظیمات فریم ورک MSTest و همچنین افزودن وابستگیهای مرتبط با فایل project.json ایی که در ابتدای بحث عنوان شد و اصلاح سازنده و متد OnConfiguring کلاس Context برنامه جهت آماده سازی آنها برای پذیرش تامین کنندههای دیگر، اکنون یک نمونه از آزمونهای واحد درون حافظهای EF Core، چنین شکلی را خواهد داشت:
using System; using System.Linq; using Core1RtmEmptyTest.DataLayer; using Core1RtmEmptyTest.Entities; using Core1RtmEmptyTest.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Core1RtmEmptyTest.MsTests { [TestClass] public class CoreTests { private readonly IServiceProvider _serviceProvider; public CoreTests() { var services = new ServiceCollection(); services.AddEntityFrameworkInMemoryDatabase() .AddDbContext<ApplicationDbContext>(options => options.UseInMemoryDatabase()); services.AddScoped<IUnitOfWork, ApplicationDbContext>(); services.AddScoped<IBlogService, BlogService>(); _serviceProvider = services.BuildServiceProvider(); } [TestMethod] public void Find_searches_url() { // Insert seed data into the database using one instance of the context using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { using (var context = serviceScope.ServiceProvider.GetRequiredService<IUnitOfWork>()) { context.Set<Blog>().Add(new Blog { Url = "http://sample.com/cats" }); context.Set<Blog>().Add(new Blog { Url = "http://sample.com/catfish" }); context.Set<Blog>().Add(new Blog { Url = "http://sample.com/dogs" }); context.SaveAllChanges(); } } // Use a separate instance of the context to verify correct data was saved to database using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { using (var context = serviceScope.ServiceProvider.GetRequiredService<IUnitOfWork>()) { Assert.AreEqual(3, context.Set<Blog>().Count()); Assert.AreEqual("http://sample.com/cats", context.Set<Blog>().First().Url); } } // Use a clean instance of the context to run the test using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { var blogService = serviceScope.ServiceProvider.GetRequiredService<IBlogService>(); var results = blogService.GetPagedBlogsAsNoTracking(pageNumber: 0, recordsPerPage: 10); Assert.AreEqual(3, results.Count); } } } }
همانطور که در قسمت «تغییرات Context برنامه جهت استفادهی از تامین کنندهی داخل حافظهای» فوق عنوان شد، در حین انجام آزمونهای واحد، دیگر به کلاس آغازین برنامه و تنظیمات آن مراجعه نمیشود. بنابراین باید شبیه به عملکرد متد ConfigureServices آنرا در اینجا پیاده سازی کرد. نمونهای از انجام اینکار را در سازندهی کلاس انجام آزمونهای واحد مشاهده میکنید:
private readonly IServiceProvider _serviceProvider; public CoreTests() { var services = new ServiceCollection(); services.AddEntityFrameworkInMemoryDatabase() .AddDbContext<ApplicationDbContext>(options => options.UseInMemoryDatabase()); services.AddScoped<IUnitOfWork, ApplicationDbContext>(); services.AddScoped<IBlogService, BlogService>(); _serviceProvider = services.BuildServiceProvider(); }
سپس همانند قبل، باید تمام سرویسهای مدنظر تنظیم شوند تا بتوان از آنها استفاده کرد.
نکتهی مهم دیگری را که باید به آن دقت داشت، ایجاد scope و سپس دسترسی به سرویسها از طریق این Scope است. از این جهت که چون خارج از طول عمر یک درخواست وب قرار داریم، دیگر Scopeها برای ما به صورت خودکار ایجاد و تخریب نمیشوند و باید همانکاری را که ASP.NET Core در پشت صحنه انجام میدهد، به صورت دستی پیاده سازی کنیم:
using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { using (var context = serviceScope.ServiceProvider.GetRequiredService<IUnitOfWork>()) {
یک نکتهی تکمیلی
EF Core به همراه تامین کنندهی بانک اطلاعاتی SQLite نیز هست. یکی از نکات ویژهی بانک اطلاعاتی SQLite، امکان تنظیم پارامتری است در رشتهی اتصالی آن، که آنرا نیز تبدیل به یک «بانک اطلاعاتی درون حافظهای» میکند. این روش سالها است که جهت انجام آزمونهای واحد ORMها مورد استفاده قرار میگیرد. بنابراین میتوان آنرا به عنوان جایگزینی برای مطلب جاری نیز درنظر گرفت.
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" }; var connectionString = connectionStringBuilder.ToString(); var connection = new SqliteConnection(connectionString); services.AddEntityFrameworkSqlite().AddDbContext<CmsDbContext>(options => options.UseSqlite(connection));
اشتراکها
3.Visual Studio 2019 RC منتشر شد
- Modal progress dialog stays open permanently even when IDE is responsive ('Preparing Solution', 'Creating Project', Edit and Continue, etc).
- PackageId:OpenJDKV1;PackageAction:Uninstall;ReturnCode:0;.
- .sql files are empty.
- Properties Window in Forms Designer shows vertical scrollbar without drag handle with automatic scaling on 4K display in Visual Studio 2019 RC.
- VSIXInstaller.exe crashes randomly when installing multiple extensions sequentially in Visual Studio 2019 RC.1.
- MSBuild failure when executing multi-line Exec commands.
- You can now use Time Travel Debugging with the snapshot debugger on ASP.NET Apps running on an Azure VM. Please note that this feature may not work in all Azure regions at release.
I’ve been kicking around the idea of combining [HttpPost] and [ValidateAntiForgeryToken] in an application using authentication cookies. Both attributes typically appear together to prevent cross-site request forgeries in MVC applications using cookie based authentication. The result looks like the following.
اشتراکها
7.Visual Studio 2017 15.9 منتشر شد
These are the customer-reported issues addressed in 15.9.7:
- Crashes when expanding variables!.
- /DEBUG:FASTLINK + C7 + PCH crashes debugger.
- Native C++ application crashes because of stack corruption with VS 2017 15.9.2.
- Incorrect Release Mode code.
- Xamarin Unobserved Task Exception WebRequest.
- Link /SOURCELINK option seems to do nothing. This fixes Source Link for Managed C++ Debugging.
- Fixed an issue with corruption of AVX/MPX/AVX512 registers while Debugging.
- Update of Microsoft.VCLibs.140.00.UWPDestkop framework packages for C++ UWP DesktopBridge applications adding support for ARM64.
- Corrected incorrect version of VCToolsRedistVersion in Microsoft.VCToolsVersion.default.props.
- Corrected unsigned embedded dll for VC Redist installers.
- SSDT/Web Tools: We fixed an issue where SQL LocalDB was not installed on Polish, Turkish, and Czech locales.
- SSDT: We fixed an issue affecting SQL Server Analysis Services (Method not found exception when clicking on UI).
- SSDT: We fixed an accessibility issue which was causing the contents of a table not to be visible in the result window when using High-Contrast mode.
Security Advisory Notices
اشتراکها
NET Core 2.2.4. منتشر شد
اشتراکها
NET Core 2.2 Preview 2. منتشر شد
اشتراکها