IMapper模拟返回null

时间:2018-11-07 13:53:56

标签: unit-testing asp.net-core moq xunit

我在.net核心中有一个应用程序,其中我在一项服务中使用了自动映射器。现在的问题是我正在编写测试方法和模拟自动映射器,但它返回null。 这是服务方法:

$qb->select('b')
    ->from(A::class, 'a')
    ->join('a.bs', 'ab')
    ->join(B::class, 'b', Join::WITH, $qb->expr()->eq('ab.id', 'b.id'))

这是使用Moq进行模拟:

var users = _mapper.Map<IList<User>>(data);

现在,此模拟程序每次都重新设置为null。我在做什么错了?

3 个答案:

答案 0 :(得分:1)

您似乎已将Moq设置为拦截对IMapper.Map<TSource, TDestination>(TSource source)重载的调用,但是被测试的代码调用了IMapper.Map<TDestination>(object source)重载。

您应该嘲笑后者:

var userLogsList = new List<User>() { new User() {Id = "1234", Name= "Dummy User"}};
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(m => m.Map<IList<User>>(It.IsAny<object>()))
          .Returns(userLogsList);

我假设here描述了IMapper的签名。

答案 1 :(得分:1)

您还可以考虑使用专门为测试配置的实际IMapper实例。

// Arrange

//Configure mapping just for this test
var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<User, UserEntity>();
    cfg.CreateMap<UserEntity, User>();
});

var mapper = config.CreateMapper(); // IMapper to be injected into subject under test

//...

如果可以使用依赖关系而没有太多的影响和最小的配置,那么就不必总是有使用模拟的理由。

在这种情况下,配置比创建模拟要简单得多,您无需任何其他工作即可获得依赖项的全部功能。

答案 2 :(得分:1)

您必须调用automapper config的原因是因为UNIT Test用例实例在主应用程序启动文件/配置之外运行。因此,必须在任何单元测试开始运行之前调用和设置自动映射器配置。理想情况下,将其放在TestInitialize方法中。