You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对含数据库交互的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:52:48