简体   繁体   English

在单元测试中模拟Automapper是一个好习惯吗?

[英]Is it a good practice to mock Automapper in unit tests?

There is this codebase where we use automapper and have 2 layers, Domain and Service . 有这个代码库,我们使用automapper并有2层, DomainService Each has its object for data representation, DomainItem and ServiceItem . 每个都有其数据表示对象, DomainItemServiceItem The service gets data from domain, the uses constructor injected automapper instance to map 服务从域获取数据,使用构造函数注入的automapper实例进行映射

class Service 
{
  public ServiceItem Get(int id)
  {
    var domainItem = this.domain.Get(id);
    return this.mapper.Map<DomainItem, ServiceItem>(domainItem);
  }
}

Assume best practices, so mapper has no side-effects and no external dependencies. 假设最佳实践,因此mapper没有副作用,也没有外部依赖。 You'd write a static function to convert one object to another within seconds, just mapping fields. 您将编写一个静态函数,在几秒钟内将一个对象转换为另一个对象,只是映射字段。

With this in mind, is it a good practice to mock the mapper in unit tests like this? 考虑到这一点,在这样的单元测试中模拟映射器是一个好习惯吗?

[TestClass]
class UnitTests
{
  [TestMethod]
  public void Test()
  {
    var expected = new ServiceItem();

    var mockDomain = new Mock<IDomain>();
    // ... setup
    var mockMapper = new Mock<IMapper>();
    mockMapper.Setup(x => x.Map<DomainItem, ServiceItem>(It.IsAny<DomainItem>()))
      .Returns(expected);


    var service = new Service(mockDomain.Object, mockMapper.Object);
    var result = service.Get(0);

    Assert.AreEqual(expected, result);
  }
}

To me, it seems that such unit test does not really bring any value, because it is effectively testing only the mocks, So i'd either not write it at all OR I'd use the actual mapper, not the mocked one. 对我来说,似乎这样的单元测试并没有真正带来任何价值,因为它只是有效地测试了模拟,所以我要么根本不要写它或者我要使用实际的映射器,而不是模拟的映射器。 Am I right or do I overlook something? 我是对的还是我忽略了什么?

I think the issue here is that the test is badly written for what it is actually trying to achieve which is testing Service.Get() . 我认为这里的问题是测试编写得非常糟糕,因为它实际上试图实现的是测试Service.Get()

The way I would write this test is as follows: 我写这个测试的方式如下:

[TestMethod]
public void Test()
{
  var expected = new ServiceItem();

  var mockDomain = new Mock<IDomain>();
  var expectedDomainReturn = new DomainItem(0); //Illustrative purposes only
  mockDomain.Setup(x => x.DomainCall(0)).Returns(expectedDomainReturn); //Illustrative purposes only

  var mockMapper = new Mock<IMapper>();
  mockMapper.Setup(x => x.Map<DomainItem, ServiceItem>(It.IsAny<DomainItem>()))
      .Returns(expected);    


  var service = new Service(mockDomain.Object, mockMapper.Object);
  var result = service.Get(0);

  mockDomain.Verify(x => x.DomainCall(0), Times.Once);
  mockMapper.Verify(x => x.Map<DomainItem, ServiceItem>(expectedDomainReturn), Times.Once);
}

This test instead of not really checking the functionality of the service.Get() , checks that the parameters passed are correct for the individual dependency calls based on the responses. 此测试不是没有真正检查service.Get()的功能,而是根据响应检查传递的参数对于各个依赖性调用是否正确。 You are thus not testing AutoMapper itself and should not need to. 因此,您不会测试AutoMapper本身,也不应该这样做。

Checking result is basically useless but will get the code coverage up. 检查result基本没用,但会获得代码覆盖率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM