在單元測試時該如何測試資料庫?難道真的要建立一個替身資料庫?還是需要使用 SQLite 或是記憶體中的假資料庫(in-memory provider)?
但是那應該是整合測試的範疇了,我只是想要做單元測試,可以模擬查詢取得資料就好,有沒有最簡單的方法?
註: 本套件適用於 NSubstitute ,如果使用 Moq 則是安裝 MockQueryable.Moq
在 Program.cs 也要增加:
使用 MockQueryable + NSubstitute 套件就可以使用下面的方式模擬假資料:
接下來就可以使用平時查詢的方式,查詢結果就會很神奇的是剛剛設定的假資料了!
但是那應該是整合測試的範疇了,我只是想要做單元測試,可以模擬查詢取得資料就好,有沒有最簡單的方法?
安裝
先使用 NuGet 安裝 MockQueryable.NSubstitute 套件,或是使用 .NET CLI 執行以下指令安裝
dotnet add package MockQueryable.NSubstitute
註: 本套件適用於 NSubstitute ,如果使用 Moq 則是安裝 MockQueryable.Moq
模擬 ApplicationDbContext
一開始要先模擬 ApplicationDbContext,而最好的方式就是建立一個介面,為了確保可以正常使用,需要有下面這三個方法,然後讓原本的 ApplicationDbContext 繼承這個 IApplicationDbContext
public interface IApplicationDbContext
{
// TODO: 或是其他資料表
// public DbSet<Calendar> Calendars { get; set; }
public int SaveChanges();
public Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken());
public DatabaseFacade Database { get; }
}
在 Program.cs 也要增加:
builder.Services.AddScoped<IApplicationDbContext, ApplicationDbContext>();
模擬查詢結果
我們有一個資料表叫做 Calendar ,在 ApplicationDbContext 中可以使用 _context.Calendars 來做查詢,一般的查詢方式如下:
List<Calendar> list = _context.Calendars
.Where(x => x.IsHoliday == true)
.ToList();
使用 MockQueryable + NSubstitute 套件就可以使用下面的方式模擬假資料:
// 建立假資料
var mockCalendars = new List<Calendar>
{
new() { Date = new DateTime(2023, 1, 1), IsHoliday = true },
new() { Date = new DateTime(2023, 1, 2), IsHoliday = true },
};
// 建立假資料集
DbSet<Calendar> mockDbSet = mockCalendars.AsQueryable().BuildMockDbSet();
// 設定假資料集
_context.Calendars.Returns(mockDbSet);
接下來就可以使用平時查詢的方式,查詢結果就會很神奇的是剛剛設定的假資料了!
List<Calendar> list = _context.Calendars
.Where(x => x.IsHoliday == true)
.ToList();
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com