首页 > 解决方案 > 为什么在单元测试控制器方法时未初始化 IObjectMapper?

问题描述

我正在为 ASP.NET Core 使用 ASP.NET 样板模板。我有一些已成功进行单元测试的应用程序服务。

我现在想测试一个使用这些应用程序服务的控制器方法。控制器方法包括如下映射操作:

var client = ObjectMapper.Map<ClientModel>(clientResponse.ClientSummary);

执行此方法时,测试失败并出现异常:

消息:Abp.AbpException:应该实现 Abp.ObjectMapping.IObjectMapper 以映射对象。

有趣的是,堆栈跟踪以NullObjectMapper.Map.

AbpAutoMapper在单元测试模块中使用与Web.Mvc模块中使用的相同的初始化:

Configuration.Modules.AbpAutoMapper().Configurators.Add(cfg =>
{
    cfg.AddProfiles(typeof(PortalTestModule).GetAssembly());
});

但是,在 MVC 应用程序的上下文中执行时,映射操作不会导致异常。

我未能Test在与 AutoMapper 相关的项目中初始化是什么?


我创建了一个重现项目。见链接。有一个名为GetFoos_Test测试控制器方法Index()的测试FoosController

public async Task GetFoos_Test()
{
    var mockFooService = new Mock<IFooAppService>();
    // ...

    var fooController = new FooController(mockFooService.Object);

    var result = await fooController.Index();

    result.ShouldNotBeNull();
}

根据@aaron 的回答,在控制器上注入 IObjectMapper 的属性确实解决了原始错误。但是,它不使用我正在尝试测试的映射。我在 MVC 模块的 Initialize 方法中创建了映射,如下所示:

public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(MyMvcModule).GetAssembly());

            Configuration.Modules.AbpAutoMapper().Configurators.Add(
               // Scan the assembly for classes which inherit from AutoMapper.Profile
               cfg =>
               {
                   cfg.AddProfiles(typeof(MyMvcModule).GetAssembly());

                   cfg.CreateMap<MyDto, MyModel>()
                       .ForMember(dest => dest.ReportTypeName, src => src.MapFrom(x => x.ReportType.Name));
... 

标签: c#unit-testingdependency-injectionaspnetboilerplateproperty-injection

解决方案


1.NullObjectMappernew实例中

IObjectMapper在注入实例时将属性注入到实例(例如控制器)中。

由于您无法在单元测试中注入控制器,因此您必须ObjectMapper直接设置。

// using Abp.ObjectMapping;

var fooController = new FooController(mockFooService.Object);
fooController.ObjectMapper = LocalIocManager.Resolve<IObjectMapper>(); // Add this line

2.NullObjectMapper在注入实例中

添加[DependsOn(typeof(AbpAutoMapperModule))]到您的测试模块。

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyTestModule : AbpModule
{
    // ...
}

推荐阅读