我想為我的 .Net 專案撰寫單元測驗用例。這就是我的控制器的樣子
using backend.Models;
using backend.services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace backend.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class GuestTypeController : ControllerBase
{
private readonly GuestTypeService _guestType;
public GuestTypeController(GuestTypeService _guestType)
{
this._guestType = _guestType;
}
[HttpGet("GuestType")]
public List<GuestType> guestType()
{
return _guestType.getGuestType();
}
}
}
這就是服務類的樣子
namespace backend.services
{
public class GuestTypeService
{
private readonly bookingengineContext dbContext;
public GuestTypeService(bookingengineContext dbContext)
{
this.dbContext = dbContext;
}
public List<GuestType> getGuestType()
{
return dbContext.GuestTypes.ToList();
}
}
}
我的控制器建構式中有服務物件。在撰寫測驗用例時,我正在呼叫我的控制器并模擬我的資料庫背景關系和服務類。但由于我的控制器在建構式中包含服務類物件,我無法對其進行測驗。測驗我的控制器的方法是什么。這是我第一次寫單元測驗。所以我很掙扎。
uj5u.com熱心網友回復:
這樣測驗實際上更容易。您可以創建所需的物件實體。您甚至不必模擬 DbContext。您可以在記憶體模式下創建一個以記憶體提供程式或 SQLite 為目標的物件。EF Core 檔案有一個部分解釋了可用的測驗選項,包括test doubles的各種選項。
存盤庫,或者至少是介面
Repository 選項并不意味著創建一個以IRepository完整 CRUD 方法命名的介面。這意味著抽象實際的資料訪問,允許它在不修改程式的其余部分的情況下進行更改。在這種情況下,您的服務正在這樣做。如果服務實作了一個介面,您可以模擬它或創建虛擬測驗服務:
public interface IGuestTypeService
{
List<GuestType> GetGuestTypes();
}
public GuestTypeService:IGuestTypeService
{
...
public List<GuestType> GetGuestTypes()
{
....
}
}
該服務應通過其介面注冊:
serviced.AddScoped<IGuestTypeService,GuestTypeService>();
并且容器應該接受介面
public class GuestTypeController : ControllerBase
{
private readonly IGuestTypeService _guestType;
public GuestTypeController(IGuestTypeService _guestType)
{
this._guestType = _guestType;
}
在您的測驗中,您可以創建一個虛擬測驗服務:
class DummyService:IGuestService
{
public List<GuestType> GuestTypes{get;set;}
public List<GuestType> GetGuestType()=>GuestTypes;
}
[Fact]
public void MyTest()
{
var guestTypes=new List<GuestType>{ ....};
var service=new DummyService {GuestTypes = guestTypes};
var controller=new GuestTypeController(service);
var actual=controller.getGuestType();
Assert.Equal(actual,guestTypes);
}
測驗 DbContext
也可以在記憶體模式或記憶體集合中創建由 SQLite 支持的 DbContext。SQLite 提供完整的 SQL 支持,而記憶體提供程式本質上是一個包裝串列并分解為復雜的操作。
SQLite記憶體部分解釋了使用 SQLite 進行測驗。
在這種情況下,測驗會創建并加載 DbContext 并將其注入到實際服務中:
public class MyTestClass:IDisposable
{
SQLiteConnection _connection;
DbContextOptions<bookingengineContext> _contextOptions;
public MyTestClass()
{
// Create and open a connection. This creates the SQLite in-memory database, which will persist until the connection is closed
// at the end of the test (see Dispose below).
_connection = new SqliteConnection("Filename=:memory:");
_connection.Open();
// These options will be used by the context instances in this test suite, including the connection opened above.
_contextOptions = new DbContextOptionsBuilder<bookingengineContext>()
.UseSqlite(_connection)
.Options;
SeedData();
}
public void Dispose() => _connection.Dispose();
bookingengineContext CreateContext() => new bookingengineContext(_contextOptions);
測驗資料通過SeedData()
void SeedData()
{
var data=new[]
{
new GuestType { ... },
new GuestType { ... }
};
using var context = new bookingengineContext(_contextOptions);
context.Database.EnsureCreated();
context.AddRange(data);
context.SaveChanges();
}
測驗可以根據需要在記憶體資料庫之上創建一個新的 DbContext。實際測驗與之前的測驗并沒有什么不同
[Fact]
public void MyTest()
{
using var db=CreateContext();
var service=new GuestTypeService(db);
var controller=new GuestTypeController(service);
var actual=controller.getGuestType();
var expected=db.GuestTypes.ToList();
Assert.Equal(actual,expected);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/507010.html
