单元测试自动映射器解析器

问题描述 投票:0回答:1

我正在将 .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);
    }
}

但我仍然遇到同样的错误。

c# automapper xunit xunit.net nsubstitute
1个回答
0
投票

如果您不从 DI 容器解析映射器,则应该能够利用名为

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
为该实现创建一个模拟。

有关此机制的更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.