ASP.NET Core测试异常排查:CreateUser触发非预期Catch的解决问询
解决
CreateAsync触发空引用异常的测试问题 看起来你在测试用户创建功能时遇到了空引用异常,而且异常被包装成了AggregateException,导致测试中途失败。我来帮你一步步排查和解决:
1. 核心问题:控制器的UserManager未正确初始化
你的测试代码里直接new UsersController(),但控制器依赖的UserManager<ApplicationUser>并没有被注入有效实例——UserManager本身需要依赖IUserStore、密码哈希器等多个服务,手动实例化控制器时这些依赖都是null,调用CreateAsync时自然会触发空引用。
修复方法:模拟或注入有效UserManager实例
用Moq框架模拟必要的依赖,给控制器提供可用的UserManager:
// 模拟IUserStore接口,实现CreateAsync的基本逻辑 var userStoreMock = new Mock<IUserStore<ApplicationUser>>(); userStoreMock.Setup(s => s.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<CancellationToken>())) .ReturnsAsync(IdentityResult.Success); userStoreMock.Setup(s => s.FindByIdAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) .ReturnsAsync((string id, CancellationToken ct) => new ApplicationUser { Id = id }); // 创建UserManager实例,传入模拟的Store,其他非必需依赖传null即可 var userManager = new UserManager<ApplicationUser>( userStoreMock.Object, null, null, null, null, null, null, null, null ); // 初始化控制器时传入这个userManager var usersController = new UsersController(userManager);
同时确保你的控制器构造函数是依赖注入的形式:
public class UsersController : ControllerBase { private readonly UserManager<ApplicationUser> _userManager; public UsersController(UserManager<ApplicationUser> userManager) { _userManager = userManager; } // 你的CreateUser方法... }
2. 检查ViewModel到Model的转换逻辑
虽然你说传入的参数非空,但要确认ModelConverter.ViewModelToModel.GetUser(userVM)是否返回了完整有效的ApplicationUser实例——比如UserName这类UserManager.CreateAsync必需的属性有没有被正确赋值?
可以在控制器里加个调试检查:
ApplicationUser user = ModelConverter.ViewModelToModel.GetUser(userVM); Debug.Assert(user != null, "转换后的User实例不能为null"); Debug.Assert(!string.IsNullOrEmpty(user.UserName), "UserName是创建用户的必填属性");
3. 避免用.Result调用异步方法
测试里的.Result会把异步异常包装成AggregateException,不仅增加排查难度,还可能导致死锁。改成异步测试方法:
[Fact] public async Task Should_AddShiftExchangeToUser() { MPContext context = CleanContext(); var usersController = new UsersController(userManager); // 用上面初始化好的userManager try { var x = await usersController.CreateUser(new ViewModels.UserVM()); var y = await usersController.CreateUser(new ViewModels.UserVM()); var result = await usersController.AddShiftExchange( new ShiftExchangeVM() { RequesterId = x.Value, ReceiverId = y.Value }, x.Value ); Assert.NotNull(result.Value); ShiftExchange shiftExchange = await context.shiftExchanges.FirstOrDefaultAsync(s => s.Id == result.Value); Assert.NotNull(shiftExchange); Assert.NotNull(shiftExchange.Receiver); Assert.NotNull(shiftExchange.Requester); } catch (Exception ex) { Assert.Null(ex); } }
这样如果有异常,你能直接看到原始的异常类型,不用再拆解AggregateException。
4. 验证CleanContext()返回的DbContext
确保CleanContext()返回的MPContext是完全初始化的,shiftExchanges DbSet已经正确配置,避免后续查询时出现空引用。
内容的提问来源于stack exchange,提问作者Samantha
相关产品推荐
相关产品推荐

