Khiem Nguyen
Khiem Nguyen

Reputation: 413

How do I write a unit test for controller use automapper?

I'm trying to write a unit test for controller to test method return all users. But I confuse How can I write unit test with automapper

Controller :

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

Controller Test:

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

Upvotes: 1

Views: 3852

Answers (4)

FelipeDrumond
FelipeDrumond

Reputation: 64

Just setup your controller calling your Automapper configuration and all your tests for that controller will work properly.

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

    };

    AutoMapperConfig.RegisterMappings();
}

Upvotes: 0

Jimmy Bogard
Jimmy Bogard

Reputation: 26765

You're trying to write a test of little to no value. Don't write this test. Use the real IUserService and use the real AutoMapper and assert against the ViewResult.

I would never unit test this code.

But if you're absolutely bent on writing this unit test, don't mock AutoMapper. Mock the 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
}

Upvotes: 1

Colin Bacon
Colin Bacon

Reputation: 15609

You can create a wrapper class for automapper with an interface. For example:

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

Then all you need to do in your tests is mock your map.

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

Upvotes: 1

D.Rosado
D.Rosado

Reputation: 5773

Configure automapper as you do on your MVC project:

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

Where AutoMapperConfiguration is a public static class like:

public class AutoMapperConfiguration
{

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

Upvotes: 6

Related Questions