使用MassTransit的InMemoryTestHarness时如何注入IPublishEndpoint
解决方法
错误原因
问题核心是服务注册顺序和容器构建时机错误:
AddMassTransitInMemoryTestHarness扩展方法本身会自动注册IPublishEndpoint、IBus等MassTransit核心接口,无需手动注册- 你在调用
BuildServiceProvider之后才尝试手动注册IPublishEndpoint,此时容器已经构建完成,后续对ServiceCollection的修改完全不会生效 - 你的业务服务(MediatR处理器、DbContext等)注册时,MassTransit相关服务还没有被添加到集合中,导致依赖缺失
修正步骤
- 调整注册顺序:先注册所有业务相关服务(MediatR、DbContext、AutoMapper等),再配置MassTransit内存测试套件,最后构建容器。
- 删掉所有手动注册
IPublishEndpoint的冗余代码。
修正后的RunBeforeAnyTests参考代码:
[OneTimeSetUp] public async Task RunBeforeAnyTests() { var dockerDbPort = await DockerDatabaseUtilities.EnsureDockerStartedAndGetPortPortAsync(); var dockerConnectionString = DockerDatabaseUtilities.GetSqlConnectionString(dockerDbPort.ToString()); var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddEnvironmentVariables(); _configuration = builder.Build(); var services = new ServiceCollection(); // 【第一步:先注册所有业务服务】 // 注册DbContext services.AddDbContext<RecipesDbContext>(opt => opt.UseSqlServer(dockerConnectionString)); // 注册AutoMapper services.AddAutoMapper(typeof(YourProfileClass)); // 注册MediatR services.AddMediatR(typeof(AddRecipeCommand).Assembly); // 其他你需要的服务注册 // 【第二步:再注册MassTransit内存测试套件】 _provider = services.AddMassTransitInMemoryTestHarness(cfg => { // 如果有测试需要的消费者可以在这里注册 }).BuildServiceProvider(true); _harness = _provider.GetRequiredService<InMemoryTestHarness>(); await _harness.Start(); }
可选扩展:验证消息发布
如果你需要在测试中确认消息确实被正常发布,可以在断言部分增加如下校验:
// 验证IRecipeAdded消息已经被发布 var messagePublished = await _harness.Published.Any<IRecipeAdded>(); messagePublished.Should().BeTrue();
内容的提问来源于stack exchange,提问作者Paul DeVito
相关产品推荐
相关产品推荐

