Reputation: 610
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
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
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