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

kob*_*490 7 structuremap unit-testing moq automapper asp.net-web-api

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

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

public MyController(IMapper mapper)
{
}
Run Code Online (Sandbox Code Playgroud)

和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));
}
Run Code Online (Sandbox Code Playgroud)

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

var mockMapper = new Mock<IMapper>();
var controller = new MyController(mockMapper.Object);
Run Code Online (Sandbox Code Playgroud)

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

Ift*_*ari 12

这可能是我的另一个解决方案

        //auto mapper configuration
        var mockMapper = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new AutoMapperProfile()); //your automapperprofile 
        });
        var mapper = mockMapper.CreateMapper();
Run Code Online (Sandbox Code Playgroud)

然后像这样调用控制器

var controller = new YourController(imapper:mapper,..otherobjects..);
Run Code Online (Sandbox Code Playgroud)

这样,它将达到目的,否则如果您为 IMapper 创建模拟对象,那么它将返回您要求它返回的内容。


Red*_*Red 10

这很简单:如果你嘲笑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
        });
Run Code Online (Sandbox Code Playgroud)

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