C# .NET注册控制器单元测试报错修复求助:ArgumentNullException
修复C# .NET RegistrationController单元测试的ArgumentNullException问题
错误原因
报错信息明确指向System.ArgumentNullException : Value cannot be null. (Parameter 'optionsAccessor'),根源是你在SetUp方法中创建UserClaimsPrincipalFactory<User>时,第二个参数传了null,而该构造函数要求optionsAccessor必须是非空值。
修复步骤及完整代码
除了修复optionsAccessor的问题,还要补充初始化其他未赋值的依赖(_configMock、_authMessageSenderOptions),同时建议使用内存数据库替代真实DbContext,避免测试影响真实数据:
using employmently_be.Data.Models; using employmently_be.DbContexts; using employmently_be.Entities; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using NUnit.Framework; using System.Threading.Tasks; using employmently_be.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; using Moq; using Microsoft.AspNetCore.Http; namespace Employmently.Tests.Controllers { [TestFixture] public class RegistrationControllerTests { private RegistrationController _registrationController; private UserManager<User> _userManager; private ILogger<EmailSender> _logger; private dbContext _dbContext; private IConfiguration _configMock; private IOptions<AuthMessageSenderOptions> _authMessageSenderOptions; [SetUp] public void SetUp() { // 1. 使用内存数据库创建DbContext,避免依赖真实数据库 var dbContextOptions = new DbContextOptionsBuilder<dbContext>() .UseInMemoryDatabase(databaseName: "TestEmploymentlyDb") .Options; _dbContext = new dbContext(dbContextOptions); // 2. 创建UserStore和UserManager,补全必要依赖 var userStore = new UserStore<User>(_dbContext); var identityOptions = Options.Create(new IdentityOptions()); var userManagerLogger = Mock.Of<ILogger<UserManager<User>>>(); _userManager = new UserManager<User>( userStore, identityOptions, new PasswordHasher<User>(), new[] { new UserValidator<User>() }, new[] { new PasswordValidator<User>() }, new UpperInvariantLookupNormalizer(), new IdentityErrorDescriber(), null, userManagerLogger ); // 3. 修复UserClaimsPrincipalFactory的实例化,传入合法的optionsAccessor var claimsFactory = new UserClaimsPrincipalFactory<User>(_userManager, identityOptions); // 4. 初始化缺失的依赖 _configMock = new Mock<IConfiguration>().Object; _authMessageSenderOptions = Options.Create(new AuthMessageSenderOptions()); _logger = new LoggerFactory().CreateLogger<EmailSender>(); // 5. 实例化RegistrationController _registrationController = new RegistrationController( _dbContext, _userManager, _configMock, _logger, _authMessageSenderOptions ); } [TearDown] public void TearDown() { // 清理内存数据库 _dbContext.Database.EnsureDeleted(); _dbContext.Dispose(); } [Test] public async Task Register_ValidModel_ReturnsSuccessResult() { // Arrange var model = new RegisterDto { Email = "testuser@test.com", Password = "Test1234!", ConfirmPassword = "Test1234!" }; // Act var result = await _registrationController.Register(model); // Assert Assert.IsNotNull(result); Assert.IsInstanceOf<OkResult>(result); } } }
关键修复点说明
- UserClaimsPrincipalFactory实例化:传入了
identityOptions(通过Options.Create(new IdentityOptions())创建的合法实例),不再传null。 - 内存数据库:使用
UseInMemoryDatabase创建临时测试数据库,测试完成后在TearDown中清理,避免数据残留。 - 依赖补全:初始化了
_configMock和_authMessageSenderOptions,避免控制器实例化时出现其他空引用异常。 - UserManager优化:添加了必要的验证器(
UserValidator、PasswordValidator),让测试更接近真实环境的行为。
内容的提问来源于stack exchange,提问作者Aleksandar Hristov
相关产品推荐
相关产品推荐

