IMapper mock returning null

Viewed 2336

I have an application in .net core in which I am using automapper in one of my service. Now the issue is I am writing test method and mocking automapper but it is returning null. Here is the service method:

var users = _mapper.Map<IList<User>>(data);

and here is mocking using Moq:

var userLogsList = new List<User>() { new User() {Id = "1234", Name= "Dummy User"}};
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(m => m.Map<List<UserEntity>, IList<User>>(It.IsAny<List<UserEntity>>()))
.Returns(userLogsList);

Now this mock returining null everytime. What am i doing wrong?

3 Answers

You can also consider using an actual IMapper instance configured specifically for the test.

// Arrange

//Configure mapping just for this test
var config = new MapperConfiguration(cfg => {
    cfg.CreateMap<User, UserEntity>();
    cfg.CreateMap<UserEntity, User>();
});

var mapper = config.CreateMapper(); // IMapper to be injected into subject under test

//...

If a dependency can be used without much knock on effect and minimal configuration then there is not always a reason to have to use a mock.

In this case the configuration is much simpler than creating a mock and you get the full functionality of the dependency with no additional work.

It looks like you've set up Moq to intercept calls to the IMapper.Map<TSource, TDestination>(TSource source) overload, but your code under test calls the IMapper.Map<TDestination>(object source) overload.

You should mock the latter:

var userLogsList = new List<User>() { new User() {Id = "1234", Name= "Dummy User"}};
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(m => m.Map<IList<User>>(It.IsAny<object>()))
          .Returns(userLogsList);

I'm assuming the signatures for IMapper as described here.

The reason you have to invoke automapper config is because, the UNIT Test cases instance runs outside of main application start up files/configs. Hence the auto mapper configuration has to be called and setup before any unit tests start to run. Ideally you place it in TestInitialize methods.

Related