Какой подход выбрать для тестирования конфигурации AutoMapper в приложении ASP.NET MVC? - PullRequest
4 голосов
/ 24 июня 2011

Мы широко используем AutoMapper в наших веб-приложениях ASP.NET MVC с подходом AutoMapViewResult, изложенным в этого вопроса . Итак, у нас есть действия, которые выглядят так:

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

Это создает скрытые точки сбоя в приложении, если запрошенное сопоставление не было настроено - то есть это не сбой во время компиляции.

Я собираюсь поставить что-то на место, чтобы проверить эти сопоставления. Поскольку для этого необходимо проверить фактическую конфигурацию AutoMapper, я предполагаю, что это должно быть сделано в рамках интеграционного тестирования? Должны ли эти тесты быть структурированы для контроллера или для объекта А как насчет возможности автоматического анализа всех вызовов AutoMapView?

Обратите внимание, что мы уже проверяем, что конфигурация AutoMapper действительна с использованием AssertConfigurationIsValid, отсутствует отображений, с которыми я хочу иметь дело.

Ответы [ 4 ]

4 голосов
/ 24 июня 2011

Если действие вашего контроллера выглядело так:

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

Тогда вы можете довольно легко, используя рефлексию, искать все действия контроллера в вашем проекте. Затем вы проверяете типы параметров действия и параметр универсального типа вашего результата действия AutoMapView. Наконец, вы спрашиваете AutoMapper, есть ли у него карта типов для этих моделей ввода / вывода. AutoMapper не имеет метода «CanMap», но вы можете использовать методы IConfigurationProvider в FindTypeMapFor:

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

Просто убедитесь, что это не ноль.

0 голосов
/ 24 апреля 2013

Я делаю что-то вроде этого.

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       
    }
}
0 голосов
/ 24 июня 2011
    [Test]
    public void MapperConfiguration()
    {
        var mapper = Web.Dto.Mapper.Instance;
        AutoMapper.Mapper.AssertConfigurationIsValid();
    }
0 голосов
/ 24 июня 2011

Вы можете использовать метод AssertConfigurationIsValid.Подробности находятся на сайте CodePlex Autopper (http://automapper.codeplex.com/wikipage?title=Configuration%20Validation)

Строго говоря, вы должны написать тест для проверки соответствия до , когда вы пишете действие контроллера, которое зависит от присутствующей конфигурации отображения.

В любом случае, вы можете использовать помощники по тестированию в проекте MvcContrib, чтобы проверить, что метод действия возвращает ожидаемые ViewResult и Model.

Вот пример:

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