Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automapper in xUnit testing and .NET Core 2.0

I have .NET Core 2.0 Project which contains Repository pattern and xUnit testing.

Now, here is some of it's code.

Controller:

public class SchedulesController : Controller
{
    private readonly IScheduleRepository repository;
    private readonly IMapper mapper;

    public SchedulesController(IScheduleRepository repository, IMapper mapper)
    {
        this.repository = repository;
        this.mapper = mapper;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);
        return new OkObjectResult(result);
    }
}

My Test Class:

public class SchedulesControllerTests
{
    [Fact]
    public void CanGet()
    {
        try
        {
            //Arrange
            Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
            mockRepo.Setup(m => m.items).Returns(new Schedule[]
            {
                new Schedule() { Id=1, Title = "Schedule1" },
                new Schedule() { Id=2, Title = "Schedule2" },
                new Schedule() { Id=3, Title = "Schedule3" }
            });

            var mockMapper = new Mock<IMapper>();
            mockMapper.Setup(x => x.Map<Schedule>(It.IsAny<ScheduleDto>()))
                .Returns((ScheduleDto source) => new Schedule() { Title = source.Title });

            SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mockMapper.Object);

            //Act
            var result = controller.Get();

            //Assert
            var okResult = result as OkObjectResult;
            Assert.NotNull(okResult);

            var model = okResult.Value as IEnumerable<ScheduleDto>;
            Assert.NotNull(model);

        }
        catch (Exception ex)
        {
            //Assert
            Assert.False(false, ex.Message);
        }
    }
}

Issue I Am facing.

My Issue is that when I run this code with database context and execute Get() method, it works fine, it gives me all results.

But when I tries to run test case, it's not returning any data of Dto object. When I debugged I found that

  1. I am getting my test object in controller using mockRepo.

  2. But it looks like Auto mapper is not initialized correctly, because while mapping it's not returning anything in

    var result = mapper.Map<IEnumerable<Schedule>, IEnumerable<ScheduleDto>>(source: repository.items);

What I tried So Far?

I followed all this answers but still it's not working.

Mocking Mapper.Map() in Unit Testing

How to Mock a list transformation using AutoMapper

So, I need help from someone who is good in xUnit and automapper, and need guidance on how to initialize mock Mapper correctly.

like image 582
Bharat Avatar asked Apr 20 '18 05:04

Bharat


People also ask

What is the use of AutoMapper in .NET core?

What is AutoMapper? AutoMapper is a simple library that helps us to transform one object type into another. It is a convention-based object-to-object mapper that requires very little configuration. The object-to-object mapping works by transforming an input object of one type into an output object of a different type.

When should I use AutoMapper?

AutoMapper is used whenever there are many data properties for objects, and we need to map them between the object of source class to the object of destination class, Along with the knowledge of data structure and algorithms, a developer is required to have excellent development skills as well.

How does AutoMapper work in C#?

The AutoMapper in C# is a mapper between two objects. That is AutoMapper is an object-object mapper. It maps the properties of two different objects by transforming the input object of one type to the output object of another type.

Is xUnit compatible with .NET framework?

It's an open source unit testing tool for . Net framework that's compatible with ReSharper, CodeRush, TestDriven.Net, and Xamarin. You can take advantage of xUnit.Net to assert an exception type easily.


1 Answers

Finally it worked for me, I followed this way How to Write xUnit Test for .net core 2.0 Service that uses AutoMapper and Dependency Injection?

Here I am posting my answer and Test Class so if needed other SO's can use.

public class SchedulesControllerTests
{
    [Fact]
    public void CanGet()
    {
        try
        {
            //Arrange
            //Repository
            Mock<IScheduleRepository> mockRepo = new Mock<IScheduleRepository>();
            var schedules = new List<Schedule>(){
                new Schedule() { Id=1, Title = "Schedule1" },
                new Schedule() { Id=2, Title = "Schedule2" },
                new Schedule() { Id=3, Title = "Schedule3" }
            };

            mockRepo.Setup(m => m.items).Returns(value: schedules);

            //auto mapper configuration
            var mockMapper = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile(new AutoMapperProfile());
            });
            var mapper = mockMapper.CreateMapper();

            SchedulesController controller = new SchedulesController(repository: mockRepo.Object, mapper: mapper);

            //Act
            var result = controller.Get();

            //Assert
            var okResult = result as OkObjectResult;
            if (okResult != null)
                Assert.NotNull(okResult);

            var model = okResult.Value as IEnumerable<ScheduleDto>;
            if (model.Count() > 0)
            {
                Assert.NotNull(model);

                var expected = model?.FirstOrDefault().Title;
                var actual = schedules?.FirstOrDefault().Title;

                Assert.Equal(expected: expected, actual: actual);
            }
        }
        catch (Exception ex)
        {
            //Assert
            Assert.False(false, ex.Message);
        }
    }
}
like image 158
Bharat Avatar answered Oct 18 '22 16:10

Bharat