我正在将 .net 与 xUnit 和 NSubstitute 一起使用。我想对从 UnitPostVModel 到 UnitBLLModel 的映射进行单元测试。使用 UnitImgUrlResolver 时出现错误,其中显示
Cannot dynamically create an instance of type 'APMAPI.ServicesBLL.Resolvers.UnitImgUrlResolver'. Reason: No parameterless constructor defined.
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<UnitPostVModel, UnitBLLModel> ()
.ForMember(dest => dest.imgUrl, opt => opt.MapFrom<UnitImgUrlResolver>());
}
}
这是我的解析器:
public class UnitImgUrlResolver : IValueResolver<UnitPostVModel, UnitBLLModel, string>
{
IAzureBlobStorageService _azureBlobStorageService;
public UnitImgUrlResolver(IAzureBlobStorageService azureBlobStorageService)
{
_azureBlobStorageService = azureBlobStorageService;
}
public string Resolve(
UnitPostVModel src,
UnitBLLModel destination,
string destMember,
ResolutionContext context)
{
if(src.image == null)
return string.Empty;
var imageName = GenerateRandomAlphaNumeric(10);
var url = _azureBlobStorageService.UploadImageToBlobStorage(src.image, imageName);
return url;
}
}
这是我的测试功能:
public class AutoMapperTests
{
private readonly IMapper _mapper;
public AutoMapperTests()
{
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<AutoMapperProfile>();
});
_mapper = config.CreateMapper();
}
[Fact]
public void Should_Map_UnitPostVModel_To_UnitBLLModel()
{
// Arrange
var unitPostVModel = new UnitPostVModel
{
abbreviation = "A",
name = "Test"
};
// Act
var result = _mapper.Map<UnitBLLModel>(unitPostVModel);
// Assert
Assert.NotNull(result);
Assert.Equal("MockedImageUrl", result.imgUrl);
}
#endregion
}
但我收到此错误:
Message:
AutoMapper.AutoMapperMappingException : Error mapping types.
Mapping types:
UnitPostVModel -> UnitBLLModel
APMAPI.Models.VModels.UnitPostVModel -> APMAPI.Models.BLLModels.UnitBLLModel
Type Map configuration:
UnitPostVModel -> UnitBLLModel
APMAPI.Models.VModels.UnitPostVModel -> APMAPI.Models.BLLModels.UnitBLLModel
Destination Member:
imgUrl
---- System.MissingMethodException : Cannot dynamically create an instance of type 'APMAPI.ServicesBLL.Resolvers.UnitImgUrlResolver'. Reason: No parameterless constructor defined.
我尝试为 IAzureBlobStorageService 创建模拟
private readonly IMapper _mapper;
private readonly IAzureBlobStorageService _azureBlobStorageService;
public AutoMapperTests()
{
// Create a mock for IAzureBlobStorageService
_azureBlobStorageService = Substitute.For<IAzureBlobStorageService>();
// Create an instance of UnitImgUrlResolver with the mock
var unitImgUrlResolver = new UnitImgUrlResolver(_azureBlobStorageService);
var config = new MapperConfiguration(cfg => {
// Register the resolver instance
cfg.CreateMap<UnitPostVModel, UnitBLLModel>()
.ForMember(dest => dest.imgUrl, opt => opt.MapFrom(src => unitImgUrlResolver.Resolve(src, null, null, null)));
});
_mapper = config.CreateMapper();
}
[Fact]
public void Should_Map_UnitPostVModel_To_UnitBLLModel()
{
// Arrange
var unitPostVModel = new UnitPostVModel
{
abbreviation = "A",
name = "Test",
description = "Test",
propertyId = Guid.NewGuid(),
type = Guid.NewGuid(),
outOfService = false
};
// Mock the method call to UploadImageToBlobStorage
_azureBlobStorageService.UploadImageToBlobStorage(Arg.Any<IFormFile>(), Arg.Any<string>())
.Returns("MockedImageUrl");
// Act
var result = _mapper.Map<UnitBLLModel>(unitPostVModel);
// Assert
Assert.NotNull(result);
Assert.Equal("MockedImageUrl", result.imgUrl);
}
}
但我仍然遇到同样的错误。
ConstructServicesUsing
的自定义扩展点来覆盖 AutoMapper 实例化解析器的方式。这应该允许您模拟它的实现:
private readonly IMapper _mapper;
public AutoMapperTests()
{
var config = new MapperConfiguration(cfg => {
cfg.ConstructServicesUsing(type => Substitute.For([type], []));
cfg.AddProfile<AutoMapperProfile>();
});
_mapper = config.CreateMapper();
}
这样,我们告诉 AutoMapper 在遇到自定义解析器或转换器实例时调用
Substitute.For([type], [])
。然后,这应该利用 NSubstitute
为该实现创建一个模拟。
有关此机制的更多信息: