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

使用xUnit和Moq测试仓储模式遇空引用异常,求学习与问题解决

问题解答

一、NullReferenceException异常原因及修复

异常根源

  1. Mock的DbContext未配置有效DbSet:你创建的Mock<TodoContext>默认不会生成可用的DbSet<User>,调用_context.Set<User>()会返回null,执行Add(entity)时触发空引用异常。
  2. 测试逻辑错位:你Mock了IRepository<User>,但实际测试的是真实UserRepository实例,最后却验证Mock对象的方法调用,两者完全无关,验证无效。

修复后的测试代码

要测试UserRepository的Create方法,需正确MockDbContext和DbSet,确保_context.Set<User>()返回有效Mock集合:

public class UserRepositoryTests
{
    [Fact]
    public async Task Create_ShouldAddEntityAndSaveChanges()
    {
        // Arrange
        var userTestObject = new User
        {
            Id = 1,
            NickName = "johnDoe",
            Email = "johndoe@email.com",
            Password = "Pass@1234",
            UserTasks = new List<UserTask>
            {
                new UserTask { Id = 1, Description = "Study C#/.NET" }
            }
        };

        // 创建Mock的DbSet<User>
        var mockDbSet = new Mock<DbSet<User>>();
        // 配置Mock的TodoContext,让Set<User>()返回Mock集合
        var mockContext = new Mock<TodoContext>();
        mockContext.Setup(c => c.Set<User>()).Returns(mockDbSet.Object);

        var repository = new UserRepository(mockContext.Object);

        // Act
        var result = await repository.Create(userTestObject);

        // Assert
        // 验证DbSet的Add方法是否被调用
        mockDbSet.Verify(d => d.Add(It.Is<User>(u => u == userTestObject)), Times.Once);
        // 验证SaveChangesAsync是否被调用一次
        mockContext.Verify(c => c.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
        // 验证返回对象与传入实体一致
        Assert.Equal(userTestObject, result);
    }
}

二、单元测试学习路径建议

  • 先掌握Mock工具核心用法:比如Moq的基础操作——创建Mock对象、设置方法返回值、验证调用次数,理解Mock的作用是隔离目标对象的依赖,避免依赖真实数据库或外部服务。
  • 聚焦仓储层测试核心:仓储层单元测试不需要验证EF Core的CRUD逻辑(官方已保证),重点是验证仓储方法是否正确调用DbContext和DbSet的对应方法(如Add、Find、SaveChanges等)。
  • 分阶段练习:
    • 先测试无状态简单方法(如GetById),学会MockDbSet的FindAsync返回指定数据。
    • 再测试数据变更方法(如Create、Update),验证Add/Update和SaveChangesAsync的调用。
  • 从官方文档入手:优先看ASP.NET Core官方单元测试指南、Moq官方基础示例,避免走弯路。

内容的提问来源于stack exchange,提问作者johnjoker13

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:27:40