AutoMapper映射StudentView后调用InsertStudentAsync返回null排查
问题原因
单元测试中Moq的参数匹配规则不生效是核心原因:
- 你在测试Arrange阶段通过
mapperMock.Map<StudentView, Student>(inputStudentView)生成了一个Student实例,用这个实例作为参数设置了InsertStudentAsync的返回规则 - 业务代码
RegisterStudentAsync执行时,会再次调用mapper.Map<Student>(student)生成全新的Student实例,两个实例的属性完全一致但属于不同的内存对象 - Moq默认按引用匹配参数,导致Setup规则无法匹配到业务代码传入的新实例,最终返回默认值null
额外可排查点:两个模型的Gender类型不同(Student是int,StudentView是Gender枚举),如果AutoMapper映射规则失效也可能导致属性异常,但不会直接导致InsertStudentAsync返回null。
解决方案
方案1:修改Moq匹配规则(推荐,可校验传入参数正确性)
将原Setup逻辑修改为按属性匹配,只要传入的Student属性符合预期就触发规则:
this.storageBrokerMock.Setup(broker => broker.InsertStudentAsync(It.Is<Student>(s => s.Id == inputStudentView.Id && s.UserId == inputStudentView.UserId && s.IdentityNumber == inputStudentView.IdentityNumber && s.FirstName == inputStudentView.FirstName && s.Gender == (int)inputStudentView.Gender // 其余需要校验的属性可按需补充 ))) .ReturnsAsync((Student input) => input);
方案2:宽松匹配(适合不需要校验参数的场景)
如果不需要验证传入InsertStudentAsync的参数是否正确,直接匹配任意Student实例即可:
this.storageBrokerMock.Setup(broker => broker.InsertStudentAsync(It.IsAny<Student>())) .ReturnsAsync((Student input) => input);
额外优化建议
添加AutoMapper配置校验,避免映射规则错误导致属性丢失:
在测试构造函数的Mapper配置创建完成后添加校验代码:
var configurationMapper = new MapperConfiguration( options => options.AddProfile(new MappingProfiles())); // 新增此行,映射配置有错误会直接抛出异常 configurationMapper.AssertConfigurationIsValid();
内容的提问来源于stack exchange,提问作者Bdruid
相关产品推荐
相关产品推荐

