如何对含数据库交互的PrintBillVM代码编写单元测试?
解决方案
首先得重构你的PrintBillVM,把数据库上下文的依赖通过构造函数注入进来,这样才能在单元测试里用Mock对象替换真实的数据库连接。
重构后的ViewModel代码
public partial class PrintBillVM : ObservableObject { [ObservableProperty] public double subTotal; [ObservableProperty] public double tax; [ObservableProperty] public double totalPrice; double taxRate = 5; private readonly DatabaseContext _dbContext; // 通过构造函数注入数据库上下文 public PrintBillVM(DatabaseContext dbContext) { _dbContext = dbContext; CalculateBill(); } // 把计算逻辑抽成单独方法,方便测试 public void CalculateBill() { var orders = _dbContext.Orders_t.Include(o => o.Product).ToList(); SubTotal = orders.Sum(i => i.Price); Tax = SubTotal * taxRate / 100; TotalPrice = SubTotal + Tax; } }
单元测试代码(使用Moq库)
先确保你已安装Moq和FluentAssertions这两个NuGet包。
public class PrintBillVMTests { [Fact] public void Calculate_TotalPrice_ShouldReturnCorrectValues() { // 1. 准备模拟订单数据:总价100,对应税5、总价105 var mockOrders = new List<Orders_t> { new Orders_t { Price = 50 }, new Orders_t { Price = 50 } }; // 2. Mock DbSet与DatabaseContext var mockDbSet = new Mock<DbSet<Orders_t>>(); mockDbSet.As<IQueryable<Orders_t>>().Setup(m => m.Provider).Returns(mockOrders.AsQueryable().Provider); mockDbSet.As<IQueryable<Orders_t>>().Setup(m => m.Expression).Returns(mockOrders.AsQueryable().Expression); mockDbSet.As<IQueryable<Orders_t>>().Setup(m => m.ElementType).Returns(mockOrders.AsQueryable().ElementType); mockDbSet.As<IQueryable<Orders_t>>().Setup(m => m.GetEnumerator()).Returns(mockOrders.AsQueryable().GetEnumerator()); var mockDbContext = new Mock<DatabaseContext>(); mockDbContext.Setup(m => m.Orders_t).Returns(mockDbSet.Object); // 3. 创建ViewModel实例,传入Mock上下文 var billVM = new PrintBillVM(mockDbContext.Object); // 4. 验证计算结果 billVM.Tax.Should().Be(5); billVM.TotalPrice.Should().Be(105); } }
关键说明
- 依赖注入:将
DatabaseContext通过构造函数传入,而非在ViewModel内部直接实例化,这样测试时可以用Mock对象替换真实数据库连接,避免依赖真实数据环境。 - Mocking:用Moq创建
DatabaseContext和DbSet的模拟实现,让它返回预设的订单数据,以此控制输入,专注验证计算逻辑的正确性。 - 抽离计算方法:把原构造函数内的计算逻辑单独提取为
CalculateBill方法,后续单独测试计算逻辑时会更灵活。
内容的提问来源于stack exchange,提问作者Kave
相关产品推荐
相关产品推荐

