【问题标题】:What approach to take for testing AutoMapper configuration in an ASP.NET MVC application?在 ASP.NET MVC 应用程序中测试 AutoMapper 配置的方法是什么?
【发布时间】:2013-04-25 02:38:39
【问题描述】:

我们在我们的 ASP.NET MVC Web 应用程序中广泛使用AutoMapper,并使用this question 中规定的 AutoMapViewResult 方法。所以我们有如下所示的操作:

public ActionResult Edit(User item)
{
    return AutoMapView<UserEditModel>(View(item));
}

如果请求的映射尚未配置,这会在应用程序中创建隐藏的故障点 - 因为这不是编译时失败。

我正在考虑采取一些措施来测试这些映射。由于这需要测试实际的 AutoMapper 配置,我认为这应该作为集成测试的一部分来完成?这些测试应该按控制者还是按实体构建?自动解析对 AutoMapView 的所有调用的可能性如何?

请注意,我们已经在使用 AssertConfigurationIsValid 测试 AutoMapper 配置是否有效,这是我要处理的缺少个映射。

【问题讨论】:

  • 您不能为您的操作方法编写单元测试吗?我错过了什么吗?
  • @Brook - 这不能真正通过单元测试来测试,因为它涉及外部代码,例如实际的 AutoMapper 配置。正常的单元测试模拟 AutoMapper。
  • 这就是为什么您应该在编写依赖于它们的代码之前测试您的 Automapper 配置。集成测试始终遵循单元测试。

标签: asp.net-mvc testing integration-testing automapper


【解决方案1】:

如果您的控制器操作如下所示:

public AutoMapView<UserEditModel> Edit(User item)
{
    return AutoMapView<UserEditModel>(View(item));
}

然后您可以很容易地使用反射查找项目中的所有控制器操作。然后检查 AutoMapView 操作结果的操作参数类型和通用类型参数。最后,您询问 AutoMapper 是否有用于这些输入/输出模型的类型映射。 AutoMapper 没有“CanMap”方法,但可以使用 FindTypeMapFor 的 IConfigurationProvider 方法:

((IConfigurationProvider) Mapper.Configuration).FindTypeMapFor(null, typeof(User), typeof(UserEditModel);

只要确保它不为空即可。

【讨论】:

    【解决方案2】:
        [Test]
        public void MapperConfiguration()
        {
            var mapper = Web.Dto.Mapper.Instance;
            AutoMapper.Mapper.AssertConfigurationIsValid();
        }
    

    【讨论】:

    • 与@Ben 的评论相同
    【解决方案3】:

    您可以使用AssertConfigurationIsValid 方法。详细信息在 automapper codeplex 网站 (http://automapper.codeplex.com/wikipage?title=Configuration%20Validation)

    严格来说,您应该在编写依赖于当前映射配置的控制器操作之前编写测试来验证映射。

    无论哪种方式,您都可以使用 MvcContrib 项目中的 Test Helpers 来检查 action 方法是否返回了预期的 ViewResult 和 Model。

    这是一个例子:

                pageController.Page("test-page")
                .AssertViewRendered()
                    .WithViewData<PortfolioViewData>()
                        .Page
                            .ShouldNotBeNull()
                            .Title.ShouldEqual("Test Page");
    

    【讨论】:

    • 您错过了重点 - 正如问题中所述,我已经在使用它来验证配置,我正在寻找的是标记我的应用程序请求的未配置映射的东西
    • 是的,我们应该写一些东西来验证映射,但是开发人员忘记了,我正在寻找一些东西来降低这种风险。
    • 那么我的更新有帮助吗?如果您没有配置映射,这会抛出。
    【解决方案4】:

    我做这样的事情。

    using System.Linq;
    using System.Reflection;
    using AutoMapper;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    public class SampleDto
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    
    public class Sample
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string LoginId { get; set; }
    }
    
    public class AutomapperConfig
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg => cfg.AddProfile<ViewModelProfile>());
        }
    }
    
    public class ViewModelProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<SampleDto, Sample>();
        }
    }
    
    [TestClass]
    public class AutoMapperTestsSample
    {
        public AutoMapperTestsSample()
        {
            AutomapperConfig.Configure();
        }
    
    
        [TestMethod]
        public void TestSampleDtoFirstName()
        {
            #region Arrange
            var source = new SampleDto();
            source.FirstName = "Jim";
            //source.LastName = "Bob";
            var dest = new Sample();
            dest.FirstName = "FirstName";
            dest.LastName = "LastName";
            dest.LoginId = "LoginId";
            #endregion Arrange
    
            #region Act
            AutoMapper.Mapper.Map(source, dest);
            #endregion Act
    
            #region Assert
            Assert.AreEqual("Jim", dest.FirstName);
            Assert.AreEqual(null, dest.LastName);
            Assert.AreEqual("LoginId", dest.LoginId);
            #endregion Assert       
        }
    
        [TestMethod]
        public void TestSampleDtoLastName()
        {
            #region Arrange
            var source = new SampleDto();
            //source.FirstName = "Jim";
            source.LastName = "Bob";
            var dest = new Sample();
            dest.FirstName = "FirstName";
            dest.LastName = "LastName";
            dest.LoginId = "LoginId";
            #endregion Arrange
    
            #region Act
            AutoMapper.Mapper.Map(source, dest);
            #endregion Act
    
            #region Assert
            Assert.AreEqual(null, dest.FirstName);
            Assert.AreEqual("Bob", dest.LastName);
            Assert.AreEqual("LoginId", dest.LoginId);
            #endregion Assert
        }
    
        /// <summary>
        /// This lets me know if something changed in the Dto object so I know to adjust my tests
        /// </summary>
        [TestMethod]
        public void TestSampleDtoReflection()
        {
            #region Arrange
            var xxx = typeof(SampleDto);
            #endregion Arrange
    
            #region Act
            #endregion Act
    
            #region Assert
            Assert.AreEqual(2, xxx.GetRuntimeFields().Count());
            Assert.AreEqual("System.String", xxx.GetRuntimeFields().Single(a => a.Name.Contains("FirstName")).FieldType.ToString());
            Assert.AreEqual("System.String", xxx.GetRuntimeFields().Single(a => a.Name.Contains("LastName")).FieldType.ToString());            
            #endregion Assert       
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多