首页 文章

如何使用StrcutureMap依赖注入在Web API测试中模拟AutoMapper IMapper对象?

提问于
浏览
4

所以我从头开始构建WebAPI,包括我在网上找到的一些最佳实践,例如依赖注入和使用自动映射器的域< - > DTO映射等 .

我的API控制器现在看起来与此类似

public MyController(IMapper mapper)
{
}

和AutoMapper注册表:

public AutoMapperRegistry()
{
    var profiles = from t in typeof(AutoMapperRegistry).Assembly.GetTypes()
                   where typeof(Profile).IsAssignableFrom(t)
                   select (Profile)Activator.CreateInstance(t);

    var config = new MapperConfiguration(cfg =>
    {
        foreach (var profile in profiles)
        {
            cfg.AddProfile(profile);
        }
    });

    For<MapperConfiguration>().Use(config);
    For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}

我也在构建一些测试用例,实现MOQ,这是我感到有些不确定的地方 . 每当调用我的控制器时,我需要传递一个IMapper,如下所示:

var mockMapper = new Mock<IMapper>();
var controller = new MyController(mockMapper.Object);

但是,如何配置IMapper以获得正确的映射?在配置Mapper之前重新创建我已经创建的相同逻辑会感觉多余 . 所以我想知道这样做的推荐方法是什么?

1 回答

  • 7

    这很简单:如果你模拟 IMapper 并将其想象为将数据从一个对象映射到另一个对象的完全抽象概念,那么你必须要对待它是一种抽象而不是暗示它背后有一个真正的自动化器 .

    首先,您根本不应该注册任何现有的配置文件,而应该设置IMapper.Map方法以在给定另一个对象时返回特定对象 .

    因此,对于用于特定方法的每个配置文件,您必须进行设置,看起来大致如下:

    var mockMapper = new Mock<IMapper>();
    mockMapper.Setup(x => x.Map<DestinationClass>(It.IsAny<SourceClass>()))
        .Returns((SourceClass source) =>
            {
                // abstract mapping function code here, return instance of DestinationClass
            });
    

    在这种情况下,您的测试对实际 IMapper 实现一无所知 - 它只是使用它来获取您希望从实际 IMapper 实现接收的数据 .

相关问题