.NET單元測試使用AutoFixture按需填充的幾種方式和最佳實(shí)踐記錄
AutoFixture
是一個(gè).NET庫,旨在簡化單元測試中的數(shù)據(jù)設(shè)置過程。通過自動生成測試數(shù)據(jù),它幫助開發(fā)者減少測試代碼的編寫量,使得單元測試更加簡潔、易讀和易維護(hù)。AutoFixture可以用于任何.NET測試框架,如xUnit、NUnit或MSTest。
默認(rèn)情況下AutoFixture生成的字段值很多時(shí)候都滿足不了測試需求,比如:
public class User { public int Id { get; set; } public string Name { get; set; } = null!; [EmailAddress] public string? Email { get; set; } [StringLength(512)] public string? Address { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; }
如果直接使用 Create<T>()
生成的User對象,他會默認(rèn)給你填充Id為隨機(jī)整數(shù),Name和Email為一串Guid,顯然這里的郵箱地址生成就不能滿足要求,并不是一個(gè)有效的郵箱格式
那么如何讓AutoFixture按需生成有效的測試數(shù)據(jù)呢?方法其實(shí)有好幾種:
方法1:直接定制
var fixture = new Fixture(); fixture.Customize<User>(c => c .With(x => x.Email, "特定值") .Without(x => x.Id));
這里,With方法用于指定屬性的具體值,而Without方法用于排除某些屬性不被自動填充。
方法2:使用匿名函數(shù)
這在需要對生成的數(shù)據(jù)進(jìn)行更復(fù)雜的操作時(shí)非常有用。
var fixture = new Fixture(); fixture.Customize<User>(c => c.FromFactory(() => new User { Email = "通過工廠方法生成", }));
方法3:實(shí)現(xiàn)ICustomization接口
對于更復(fù)雜的定制需求,可以通過實(shí)現(xiàn)ICustomization接口來創(chuàng)建一個(gè)定制化類。這種方法的好處是可以重用定制邏輯,并且使得測試代碼更加整潔。
public class MyCustomClassCustomization : ICustomization { public void Customize(IFixture fixture) { fixture.Customize<User>(c => c .With(x => x.Email, "自定義值") .Without(x => x.Id)); } } // 使用定制化 var fixture = new Fixture(); fixture.Customize(new MyCustomClassCustomization());
方法4:使用Build<T>
方法
Build<T>
方法提供了一種鏈?zhǔn)秸{(diào)用的方式來定制類型的生成規(guī)則,這在只需要對單個(gè)對象進(jìn)行簡單定制時(shí)非常方便。
var myCustomObject = fixture.Build<User>() .With(x => x.Email, $"{Guid.NewId()}@example.com") .Without(x => x.Id) .Create();
最佳實(shí)踐:
這里以xunit
測試框架為例,
我們需要提前引用AutoFixture
,AutoFixture.Xunit2
庫,實(shí)現(xiàn)一個(gè)UserAutoDataAttribute
類,繼承自InlineAutoDataAttribute
重寫GetData
方法,大致代碼如下:
public class UserAutoDataAttribute : InlineAutoDataAttribute { public UserAutoDataAttribute(params object[] values) : base(values) { ArgumentNullException.ThrowIfNull(values[0]); } public override IEnumerable<object[]> GetData(MethodInfo testMethod) { var fixture = new Fixture(); //這里使用上面的4種方式的一種,亦或者根據(jù)自身情況定制! var user = fixture.Build<User>() //.With(x => x.Id, 0) .Without(x => x.Id) //ID需要排除因?yàn)镋FCore需要插入時(shí)自動生成 .With(x => x.Email, $"{Uuid7.NewUuid7()}@example.com") //郵箱地址,需要照規(guī)則生成 .Create(); yield return new object[] { Values[0], user }; } }
下面是一個(gè)測試用例,需要填充db,和一個(gè)自動生成的User參數(shù)
public class UnitOfWorkTests(ITestOutputHelper output) { [Theory] [UserAutoData(1)] [UserAutoData(2)] public async Task MyUnitOfWorkTest(int db, User user) { var services = new ServiceCollection(); services.AddLogging(); services.AddDbContext<TestDbContext>(options => { options.UseInMemoryDatabase($"test-{db}"); }); services.AddUnitOfWork<TestDbContext>(); var provider = services.BuildServiceProvider(); var uow = provider.GetRequiredService<IUnitOfWork<TestDbContext>>(); //add user await uow.GetRepository<User>().InsertAsync(user); await uow.SaveChangesAsync(); // select user var user2 = await uow.GetRepository<User>().FindAsync(1); Assert.NotNull(user2); // delete user uow.GetRepository<User>().Delete(1); var row = await uow.SaveChangesAsync(); Assert.Equal(1, row); // select user user2 = await uow.GetRepository<User>().GetFirstOrDefaultAsync(x => x.Id == 1); Assert.Null(user2); } }
如果你已經(jīng)習(xí)慣編寫單元測試,但還沒有使用AutoFixture
,那么推薦你嘗試一下,也許你也會喜歡上TA
到此這篇關(guān)于.NET單元測試使用AutoFixture按需填充的幾種方式和最佳實(shí)踐記錄的文章就介紹到這了,更多相關(guān).NET單元測試使用AutoFixture按需填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
asp.net Server.MapPath方法注意事項(xiàng)
當(dāng)我發(fā)布之后,對存儲圖片的文件夾創(chuàng)建了虛擬目錄,并賦予該目錄寫入的權(quán)限,但是,當(dāng)我上傳圖片的時(shí)候,總是失敗。以前沒遇到過這種情況,覺得很是怪異,所以想盡辦法去解決。2008-09-09.Net Core和jexus配置HTTPS服務(wù)方法
下面小編就為大家分享一篇.Net Core和jexus配置HTTPS服務(wù)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02使用微信PC端的截圖dll庫實(shí)現(xiàn)微信截圖功能
這篇文章主要為大家詳細(xì)介紹了使用微信PC端的截圖dll庫實(shí)現(xiàn)微信截圖功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06asp.net core為IHttpClientFactory添加動態(tài)命名配置
某些時(shí)候我們需要為HttpClient動態(tài)配置一些東西, 例如證書等, 例如服務(wù)是一個(gè)回調(diào)服務(wù), 而被回調(diào)方采用了自定義的https(即自定義證書),本文就將講述如何實(shí)現(xiàn)這種需求2021-06-06ASP.NET Core實(shí)現(xiàn)中間件的幾種方式
這篇文章介紹了ASP.NET Core實(shí)現(xiàn)中間件的幾種方式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08asp.net+sqlserver實(shí)現(xiàn)的簡單高效的權(quán)限設(shè)計(jì)示例
大部分系統(tǒng)都有權(quán)限系統(tǒng)。一般來說,它能管控人員對某個(gè)否頁面的訪問;對某些字段、控件可見或者不可見。對gridview中的數(shù)據(jù)是否可刪除、可添加、可新增等等。2010-04-04asp.net網(wǎng)站底部的版權(quán)信息實(shí)現(xiàn)代碼且可維護(hù)
網(wǎng)站底部的版權(quán)信息在特殊情況還是比較重要的所以在實(shí)現(xiàn)的時(shí)候一定要盡可能的做到可維護(hù)性,接下來將介紹一些技巧可達(dá)到可維護(hù)效果,感興趣的你可不要錯(cuò)過了哈2013-02-02Visual Studio 2017中找回消失的“在瀏覽器中查看”命令
這篇文章主要為大家詳細(xì)介紹了如何在Visual Studio 2017中找回消失的“在瀏覽器中查看”命令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03