在ASP.NET MVC应用程序中测试AutoMapper配置的方法是什么?

时间:2011-06-24 10:41:23

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

我们在ASP.NET MVC Web应用程序中广泛使用AutoMapper,并在this question中设置了AutoMapViewResult方法。所以我们的行动看起来像这样:

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

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

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

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

4 个答案:

答案 0 :(得分:4)

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

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);

请确保不为空。

答案 1 :(得分:0)

您可以使用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");

答案 2 :(得分:0)

    [Test]
    public void MapperConfiguration()
    {
        var mapper = Web.Dto.Mapper.Instance;
        AutoMapper.Mapper.AssertConfigurationIsValid();
    }

答案 3 :(得分:0)

我这样做。

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       
    }
}