【问题标题】:How do I write a unit test for controller use automapper?如何为控制器使用 automapper 编写单元测试?
【发布时间】:2015-02-19 11:36:40
【问题描述】:

我正在尝试为控制器编写单元测试以测试方法返回所有用户。但我很困惑如何使用 automapper 编写单元测试

控制器:

private readonly IUserService _userService;

public UserController(IUserService userService)
{
  this._userService = userService;
}

public ActionResult List()
{
  var users = _userService.GetAllUsers().ToList();
  var viewModel = Mapper.Map<List<UserViewModel>>(users);
  return View(viewModel);
}

控制器测试:

    private Mock<IUserService> _userServiceMock;
    UserController objUserController;
    List<UserViewModel> listUser;

    [SetUp]
    public void Initialize()
    {
        _userServiceMock = new Mock<IUserService>();
        objUserController = new UserController(_userServiceMock.Object);
        listUser = new List<UserViewModel>()
        {
            new UserViewModel() {Id = 1, Active = true, Password = "123456", UserName = "hercules"},
            new UserViewModel() {Id = 2, Active = false, Password = "1234567", UserName = "alibaba"},
            new UserViewModel() {Id = 3, Active = true, Password = "12345678", UserName = "robinhood"},
        };
    }

    [Test]
    public void Index_Returns_AllUser()
    {
      // How do I here ???
    }

【问题讨论】:

  • 对于初学者来说,_userService.GetAllUsers() 实际返回的内容以及您打算如何处理 listUser

标签: asp.net-mvc unit-testing nunit automapper


【解决方案1】:

像在 MVC 项目上一样配置自动映射器:

[SetUp]
public void Initialize()
{
    ....
    AutoMapperConfiguration.Configure();
}

AutoMapperConfiguration 是一个公共静态类,例如:

public class AutoMapperConfiguration
{

    /// <summary>
    /// Maps between VIEWMODEL and MODEL
    /// </summary>
    public static void Configure()
    {
        //maps here
         Mapper.CreateMap..
    }
}

【讨论】:

    【解决方案2】:

    您正在尝试编写几乎没有价值的测试。不要写这个测试。使用真正的 IUserService 并使用真正的 AutoMapper 并对 ViewResult 进行断言。

    我永远不会对这段代码进行单元测试。

    但是,如果您一心想编写这个单元测试,请不要模拟 AutoMapper。模拟 IUserService。

    UserController objUserController;
    List<User> listUser;
    
    [SetUp]
    public void Initialize()
    {
        var userServiceMock = new Mock<IUserService>();
        listUser = new List<User>()
        {
            new User() {Id = 1, Active = true, Password = "123456", UserName = "hercules"},
            new User() {Id = 2, Active = false, Password = "1234567", UserName = "alibaba"},
            new User() {Id = 3, Active = true, Password = "12345678", UserName = "robinhood"},
        };
        userServiceMock.Setup(framework => framework.GetAllUsers())
      .Returns(listUser);
    
        objUserController = new UserController(_userServiceMock.Object);
    }
    
    [Test]
    public void Index_Returns_AllUser()
    {
        var result = objUserController.List();
    
        var viewResult = result as ViewResult;
    
        viewResult.ShouldNotBe(null);
        var model = viewResult.Model as List<UserListModel>;
        model.ShouldNotBe(null);
    
        model.Count.ShouldBe(3); // Don't do more than this
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用接口为 automapper 创建一个包装类。例如:

      public interface IMapperWrapper
      {
           object Map(object source, Type sourceType, Type destinationType);
      }
      

      那么您在测试中需要做的就是模拟您的地图。

      automapperWrapperMock.Setup(x => x.Map, type, type);
      

      【讨论】:

        【解决方案4】:

        只需设置您的控制器调用您的 Automapper 配置,您对该控制器的所有测试都会正常工作。

        [TestInitialize]
        public void Setup()
        {
            controller = new yourController(_unitOfWork.Object, _someRepository.Object)
            {
        
            };
        
            AutoMapperConfig.RegisterMappings();
        }
        

        【讨论】:

          猜你喜欢
          • 2010-09-12
          • 2020-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多