user3799325
user3799325

Reputation: 610

AutoMapper Test for IQueryable Mapping

public List<Models.Employer> GetEmployers()
{

    List<Models.Employer> empList = new List<Models.Employer>();
    var list = DataCentralDbContext.Employers.ToList();
    foreach (Data.Web.Employer e in list)
    {
        empList.Add(Mapper.Map<Data.Web.Employer, Models.Employer>(e));

    }
    return empList;
}

I want to Test the above method that has a dependency on the AutoMapper. Below is the code from Test Method.

var data = new List<Data.Web.Employer>
{
    new Data.Web.Employer {EmployerID= new Guid(), EmployerName = "BBB", AddressLine1="address 1", AddressLine2="address 2", City="City1",State="we",IsActive=true, PostalCode="12345" },
    new Data.Web.Employer {EmployerID= new Guid(), EmployerName = "ZZZ",AddressLine1="address 1", AddressLine2="address 2", City="City1",State="we",IsActive=true, PostalCode="12345"  },
    new Data.Web.Employer {EmployerID= new Guid(), EmployerName = "AAA",AddressLine1="address 1", AddressLine2="address 2", City="City1",State="we",IsActive=true, PostalCode="12345"  },
}.AsQueryable();

var mockSet = new Mock<DbSet<Data.Web.Employer>>();
mockSet.As<IQueryable<Data.Web.Employer>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Data.Web.Employer>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Data.Web.Employer>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Data.Web.Employer>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

var mockContext = new Mock<IDataCentralDbContext>();
mockContext.Setup(c => c.Employers).Returns(mockSet.Object);


var mapperMock = new Mock<IMapper>();
mapperMock.Setup(m => m.Map<CSF.Data.Web.Employer, CSF.Models.Employer>(It.IsAny<CSF.Data.Web.Employer>()));


var emplogic = new EmployerLogic(mockContext.Object, mapperMock.Object);

var result = emplogic.GetEmployers();

I do get back the correct Count but objects are all Null. I tried using Returns, but than it only returns one object. Is it possible to Return the collection ?

Upvotes: 0

Views: 476

Answers (2)

Jimmy Bogard
Jimmy Bogard

Reputation: 26765

Don't mock IQueryable. Don't mock IMapper. Don't mock DbContext. It's a unit test that provides zero value, there is WAY to much going on underneath the covers. Provide a facade for these, or what I do, just write an integration test that uses the real things. That DOES provide value.

Upvotes: 1

Nkosi
Nkosi

Reputation: 247018

Setup the Returns to manually do the mapping in the test

mapperMock
    .Setup(m => m.Map<CSF.Data.Web.Employer, CSF.Models.Employer>(It.IsAny<CSF.Data.Web.Employer>()))
    .Returns((CSF.Data.Web.Employer e) => new CSF.Models.Employer { 
        EmployerID = e.EmployerID, 
        EmployerName = e.EmployerName,
        //....other code removed for brevity
    });

Also when mocking the enumerator use a function.

mockSet
    .As<IQueryable<Data.Web.Employer>>()
    .Setup(x => x.GetEnumerator()).Returns(() => data.GetEnumerator());

to allow multiple enumerations as passing just .Returns(data.GetEnumerator()) will only allow one pass through the enumeration with is being used up by the ToList extension method.

I learned that the hard way after countless hours trying to figure why my tests were failing.

Upvotes: 0

Related Questions