如何使用 SQLite 对 ASP.NET 5 进行 xUnit 测试
How to xUnit Test an ASP.NET 5 with Sqlite
使用 Microsoft.Data.Sqlite,它会尝试在 wwwroot 目录中找到数据库文件26=] 5 个项目(空模板)。
如何正确地对这种项目进行xUnit测试?如果我将此 ASP.NET 项目引用到我的 xUnit 测试项目,它肯定会使用 xUnit 测试项目的目录作为基础。
更新 1
我想使用 xUnit 执行集成测试。感谢有人向我澄清了事情。
单元测试背后的想法是仅测试 class 的特定功能而不依赖它(如数据库、文件系统或网络)。
为了实现这一点,您需要在设计 classes 时考虑到控制反转,并将必要的类型抽象为接口。
想象一个 OrdersService
class 可能会获取订单数量或所有订单的总和,并且您想测试它的逻辑。
public interface IOrdersRepository
{
IEnumerable<Order> GetOrdersForCustomer(Guid customerId);
}
public class OrdersService : IOrdersService
{
private readonly IOrdersRepository ordersRepository;
// pass the orders repository that abstracts the database access
// as a dependency, so your OrdersService can be tested in isolation
public OrdersService(IOrdersRepository ordersRepository)
{
this.ordersRepository = ordersRepository
}
public int GetOrdersCount(Customer customer)
{
return ordersRepository.GetOrdersForCustomer(customer.Id).Count();
}
public decimal GetAllOrdersTotalSum(Customer customer)
{
return ordersRepository.GetOrdersForCustomer(customer.Id).Sum(order => order.TotalSum);
}
}
然后在你的单元测试中你会做类似
的事情
[Fact]
public void CalculateOrderTotalSumTest()
{
// customer id we want to check
Guid customerId = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354");
// Our test data
List<Order> orders = new List<Order>()
{
new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 100.0m),
new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 50.0m)
}
// Create a mock of the IOrdersRepository
var ordersRepositoryMock = new Mock<IOrdersRepository>();
// Next you need to set up the mock to return a certain value
ordersRepositoryMock
.Setup( m => m.ordersRepositoryMock(It.Is<Guid>( cId => cId == customerId) )
.Returns(orders);
decimal totalSum = ordersRepositoryMock.Object.GetAllOrdersTotalSum(customerId);
Assert.AreEqual(150.0m, totalSum, "Total sum doesn't match expected result of 150.0m");
ordersRepositoryMock.VerifyAll();
}
这样您就可以在不需要数据库的情况下单独测试 classes。如果您在单元测试中需要数据库、文件系统上的文件或网络连接,那么您在设计类型方面做得不好。
使用 Microsoft.Data.Sqlite,它会尝试在 wwwroot 目录中找到数据库文件26=] 5 个项目(空模板)。
如何正确地对这种项目进行xUnit测试?如果我将此 ASP.NET 项目引用到我的 xUnit 测试项目,它肯定会使用 xUnit 测试项目的目录作为基础。
更新 1
我想使用 xUnit 执行集成测试。感谢有人向我澄清了事情。
单元测试背后的想法是仅测试 class 的特定功能而不依赖它(如数据库、文件系统或网络)。
为了实现这一点,您需要在设计 classes 时考虑到控制反转,并将必要的类型抽象为接口。
想象一个 OrdersService
class 可能会获取订单数量或所有订单的总和,并且您想测试它的逻辑。
public interface IOrdersRepository
{
IEnumerable<Order> GetOrdersForCustomer(Guid customerId);
}
public class OrdersService : IOrdersService
{
private readonly IOrdersRepository ordersRepository;
// pass the orders repository that abstracts the database access
// as a dependency, so your OrdersService can be tested in isolation
public OrdersService(IOrdersRepository ordersRepository)
{
this.ordersRepository = ordersRepository
}
public int GetOrdersCount(Customer customer)
{
return ordersRepository.GetOrdersForCustomer(customer.Id).Count();
}
public decimal GetAllOrdersTotalSum(Customer customer)
{
return ordersRepository.GetOrdersForCustomer(customer.Id).Sum(order => order.TotalSum);
}
}
然后在你的单元测试中你会做类似
的事情[Fact]
public void CalculateOrderTotalSumTest()
{
// customer id we want to check
Guid customerId = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354");
// Our test data
List<Order> orders = new List<Order>()
{
new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 100.0m),
new Order() { Customer = new Guid("64f52c5c-44b4-4adc-9760-5a03d6f98354"), TotalSum = 50.0m)
}
// Create a mock of the IOrdersRepository
var ordersRepositoryMock = new Mock<IOrdersRepository>();
// Next you need to set up the mock to return a certain value
ordersRepositoryMock
.Setup( m => m.ordersRepositoryMock(It.Is<Guid>( cId => cId == customerId) )
.Returns(orders);
decimal totalSum = ordersRepositoryMock.Object.GetAllOrdersTotalSum(customerId);
Assert.AreEqual(150.0m, totalSum, "Total sum doesn't match expected result of 150.0m");
ordersRepositoryMock.VerifyAll();
}
这样您就可以在不需要数据库的情况下单独测试 classes。如果您在单元测试中需要数据库、文件系统上的文件或网络连接,那么您在设计类型方面做得不好。