.NET Core Web API单元测试中Mapper映射返回null的问题咨询
我正在开发一个.NET Core Web API项目,并为方法编写单元测试。其中一个测试用例无法得到预期输出。
测试项目中的代码如下:
_mockBaseDbContext.Setup(c => c.Transactions).Returns(mockTransactions.Object); var actualResult = await _service.Get(transactionId);
Web API中对应的方法如下:
public async Task<TransactionViewModel> Get(Guid id) { var transaction = await GetById(id); var result = _mapper.Map<TransactionViewModel>(transaction); return result; }
运行测试用例时,能够正常找到transaction:
var transaction = await GetById(id); //works fine
但无法将Transaction映射为TransactionViewModel:
_mapper.Map<TransactionViewModel>(transaction); //returns null
我在Startup.cs中配置了映射配置文件,且运行Web API时正常——我编写了一个接收Guid参数的端点,调用该方法后能正常返回TransactionViewModel:
CreateMap<Transaction, TransactionViewModel>() .ForMember(dest => dest.Client, opt => opt.MapFrom(src => src.Client)) .ForMember(dest => dest.ShopId, opt => opt.MapFrom(src => src.ShopId));
请问如何让测试中的Get方法返回正确的ViewModel?
问题出在单元测试环境中没有正确初始化AutoMapper——你在Startup里的配置是针对Web API运行时的,但测试项目并不会加载Startup的配置,所以测试用的_mapper实例没有加载你的映射规则,导致映射返回null。
解决步骤:
在测试项目中初始化AutoMapper,加载你的映射配置文件:
直接在测试类的初始化逻辑(比如构造函数或[SetUp]方法)中配置:var configuration = new MapperConfiguration(cfg => { cfg.CreateMap<Transaction, TransactionViewModel>() .ForMember(dest => dest.Client, opt => opt.MapFrom(src => src.Client)) .ForMember(dest => dest.ShopId, opt => opt.MapFrom(src => src.ShopId)); // 若有其他映射规则,需一并添加 }); var mapper = configuration.CreateMapper();如果你已经把映射规则单独封装到Profile类(比如
TransactionProfile)中,可直接加载该Profile避免重复代码:var configuration = new MapperConfiguration(cfg => { cfg.AddProfile<TransactionProfile>(); }); var mapper = configuration.CreateMapper();将初始化好的mapper注入测试用的service:
确保测试时使用的_service实例,传入的是上述正确初始化的mapper,而非未配置的空实例或mock对象。验证映射配置(可选但推荐):
在初始化配置后添加验证逻辑,提前发现映射规则中的错误:configuration.AssertConfigurationIsValid();这能帮你快速定位诸如源字段不存在、目标字段无法匹配等问题。
内容的提问来源于stack exchange,提问作者Engin Deniz Kopan

