NUnit测试使用In-Memory Database时遭遇connectionString空引用异常
问题分析与解决方案
问题根源
- 配置为空导致连接字符串获取失败:你的测试代码中,
IConfiguration是通过new ConfigurationBuilder().AddInMemoryCollection().Build()创建的空配置,完全没有加载appsettings.json里的连接字符串。而Startup.ConfigureServices中调用options.UseSqlServer(Configuration.GetConnectionString("Database"))时,因为配置为空,GetConnectionString直接返回null,触发了ArgumentNullException。 - DbContext注册顺序错误:你以为后续调用
services.AddDbContext<ApplicationDbContext>(...)能覆盖Startup里的注册,但实际上Startup的ConfigureServices先执行,在解析连接字符串那一步就已经抛出错误,根本轮不到后续的覆盖逻辑生效。
解决方法
方法一:给测试配置添加假连接字符串
在构建IConfiguration时手动添加一个非空的连接字符串占位符,绕过Startup里的空值检查:
var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary<string, string> { {"ConnectionStrings:Database", "Fake_Connection_String"} // 随便填非空字符串即可 }) .Build();
这样Startup里的UseSqlServer能拿到非空值,虽然不会真的使用这个连接(后续会被In-Memory配置覆盖),但能顺利跳过空参数校验。
方法二:替换已注册的DbContext服务(更推荐)
直接移除Startup中注册的DbContext配置,再重新注册In-Memory版本:
// 先调用Startup的服务配置 var startup = new Startup(configuration, envMock.Object); startup.ConfigureServices(services); // 移除已有的DbContextOptions注册 var dbContextDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>)); if (dbContextDescriptor != null) { services.Remove(dbContextDescriptor); } // 注册In-Memory数据库的DbContext services.AddDbContext<ApplicationDbContext>(options => options.UseInMemoryDatabase("TestDb_Sc1"));
这种方式能彻底替换掉Startup里的SqlServer配置,从根源避免连接字符串的问题。
额外注意点
测试代码里的dbContext.Buyers.Add(testBuyer);变量名错误,应该是buyerTestData,需要修正否则会出现编译错误:
dbContext.Buyers.Add(buyerTestData); dbContext.Topics.Add(topicTestData);
内容的提问来源于stack exchange,提问作者Boris Rusinov
相关产品推荐
相关产品推荐

