简体   繁体   English

我应该在单元测试中使用 AutoMapper 吗?

[英]Should I use AutoMapper in my unit tests?

I'm writing unit tests for ASP.NET MVC controller methods.我正在为 ASP.NET MVC 控制器方法编写单元测试。

Those controllers have a dependency on IMapper - an interface I've created to abstract AutoMapper, passed in via constructor injection using Castle Windsor.这些控制器依赖于IMapper我为抽象 AutoMapper 而创建的接口,使用 Castle Windsor 通过构造函数注入传入。

Action methods use IMapper to map from domain objects to ViewModel objects and back again, aiming to keep things DRY and keep action methods succinct. Action 方法使用IMapper从域对象映射到 ViewModel 对象并再次映射回来,旨在保持事物 DRY 并保持 action 方法简洁。

In my unit tests, should I在我的单元测试中,我应该

  1. Configure AutoMapper with the correct bindings (they're built using AutoMapper profiles, so testable and reusable between website and unit test projects) and pass that in as a proper AutoMapper implementation of IMapper .使用正确的绑定配置 AutoMapper(它们是使用 AutoMapper 配置文件构建的,因此可在网站和单元测试项目之间进行测试和重用)并将其作为IMapper的正确 AutoMapper 实现传递。

  2. Pass in mock objects (I'm using Moq) for the IMapper instance, depending on the test (this would mean duplicating some work in the test setup code to make sure the objects returned from the mock mapper relate to the objects the mock mapper is pretending to map).根据测试,为IMapper实例传入模拟对象(我正在使用 Moq)(这意味着在测试设置代码中重复一些工作,以确保从模拟映射器返回的对象与模拟映射器的对象相关假装地图)。

  3. Hand-configure AutoMapper with just the mappings I think I'll need for each test (lot of work and means I'm not testing the mappings that will really be in use).手动配置 AutoMapper,仅使用我认为每次测试所需的映射(大量工作,意味着我没有测试真正使用的映射)。

What's the opinion on using infrastructure code in unit tests?对在单元测试中使用基础设施代码有何看法? At what point does it become an integration test (ie testing integration of AutoMapper and my controllers)?它在什么时候成为集成测试(即测试 AutoMapper 和我的控制器的集成)?

It feels like 2 is the purist view, though I think I need to learn more about Moq and how to get it to return values that relate to the actual values passed into the methods that it's mocking.感觉 2 是纯粹的观点,尽管我认为我需要更多地了解 Moq 以及如何让它返回与传递给它所模拟的方法的实际值相关的值。

I'm in favour of #2 like jeriley我赞成像杰里利这样的#2

Adding to the Moq, if you need to return an object based on values passed to it you can write your setup like so:添加到最小起订量,如果您需要根据传递给它的值返回一个对象,您可以像这样编写您的设置:

mockObject.Setup(x => x.MapObject(It.IsAny())
          .Returns((ProductDto productDto) => 
           {
               var product = new Product()
               {
                   Id = productDto.Id,
                   Name = productDto.Name
               };

               return product
           });

Little bit messy but handy.有点凌乱但很方便。

I could tend to agree with #2.我倾向于同意#2。 You know automapper works, you know your injection works ( got tests for that right? :-) ) I would focus more on specifics, things that aren't just SomeClass.Property = AnotherClass.Property -- THOSE special cases should be tested not basic copy functions.你知道自动映射器工作,你知道你的注入工作(得到测试对吗?:-))我会更多地关注细节,不仅仅是 SomeClass.Property = AnotherClass.Property - 那些特殊情况不应该被测试基本复印功能。 Don't test framework stuff.不要测试框架的东西。

As for more test code - I feel that's completely ok.至于更多的测试代码——我觉得完全可以。 Tests should be setup within the given tests (also within reason) for just that given unit.测试应该在给定的测试中(也在合理的范围内)为给定的单元设置。

Regarding Moq, syntax is easy, don't overthink it.关于起订量,语法很简单,不要想太多。 var obj = new Mock<T>(); then set your properties like obj.Setup(x => x.Property).returns("hello") unless you have a more specific issue?然后设置您的属性,如obj.Setup(x => x.Property).returns("hello")除非您有更具体的问题? Moq also has setup all properties on it as well, so you may not even need automapper Moq 还设置了所有属性,因此您甚至可能不需要自动映射器

-edit- found it, it's obj.SetupAllProperties() ; -edit- 找到了,它是obj.SetupAllProperties()

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

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