I'm new to Moq Framework and Unit Testing in general, I'm trying to create a unit test for my repository function below.
Repository Method
public IQueryable<Campaign> AllIncluding(params Expression<Func<Campaign, object>>[] includeProperties)
{
IQueryable<Campaign> query = _context.Campaigns;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
Unit Test with Moq Setup
//Arrange
var data = new List<Models.Campaign>
{
new Models.Campaign { Id = 1, Name = "Campaign Past", StartDate = DateTime.Now.AddDays(-10), EndDate = DateTime.Now.AddDays(-5) },
new Models.Campaign { Id = 2, Name = "Campaign Active", StartDate = DateTime.Now.AddDays(-4), EndDate = DateTime.Now.AddDays(3) },
new Models.Campaign { Id = 2, Name = "Campaign Future", StartDate = DateTime.Now.AddDays(4), EndDate = DateTime.Now.AddDays(10) }
}.AsQueryable();
var _moqSet = new Mock<DbSet<Models.Campaign>>();
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.Provider).Returns(data.Provider);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.Expression).Returns(data.Expression);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.ElementType).Returns(data.ElementType);
_moqSet.As<IQueryable<Models.Campaign>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
_moqSet.As<IQueryable<Models.Campaign>>()
.Setup(m => m.Include(It.IsAny<Expression<Func<Models.Campaign, object>>>()))
.Returns((Expression<Func<Models.Campaign, object>> predicate) =>
{
return _moqSet.Object.Include(predicate);
});
var _moqContext = new Mock<Context.IPrizeSelectionContext>();
_moqContext.Setup(m => m.Campaigns).Returns(_moqSet.Object);
Func<IQueryable<Models.Campaign>, Expression<Func<Models.Campaign, object>>, IQueryable<Models.Campaign>> includeMethod = (query, expression) =>
{
return query.Include(expression);
};
//Act
List<Models.Campaign> allResults = null;
using (var sut = new CampaignRepository(_moqContext.Object, includeMethod))
{
allResults = sut.AllIncluding(o => o.Id, o => o.Name).OrderBy(o => o.Id).ToList();
}
//Assert
Assert.IsNotNull(allResults);
Assert.AreEqual(3, allResults.Count);
Assert.IsNull(allResults[0].StartDate);
I'm getting a null data after the query.include(includeProperty)
I've tried to mock the include function but I get an Expression references a method that does not belong to the mocked object: m => m.Include<Campaign,Object>(It.IsAny<Expression'1>())
exception when trying to setup the Mock DbSet. After some digging I've found that Moq has issues or can't mock extension methods, see Question Mocking Extionsion Methods with Moq
Following the steps in This Blog I've tried to execute the delegate pattern
Repository Re-write
Func<IQueryable<Campaign>, Expression<Func<Campaign, object>>, IQueryable<Campaign>> _includeMethod = null;
...
public CampaignRepository(IPrizeSelectionContext context, Func<IQueryable<Campaign>, Expression<Func<Campaign, object>>, IQueryable<Campaign>> includeMethod)
: this(context)
{
_includeMethod = includeMethod;
}
...
public IQueryable<Campaign> AllIncluding(params Expression<Func<Campaign, object>>[] includeProperties)
{
IQueryable<Campaign> query = _context.Campaigns;
foreach (var includeProperty in includeProperties)
{
if (_includeMethod == null)
query = query.Include(includeProperty);
else
query = _includeMethod(query, includeProperty);
}
return query;
}
Here is my Unit Test setup
Func<IQueryable<Models.Campaign>, Expression<Func<Models.Campaign, object>>, IQueryable<Models.Campaign>> includeMethod = (query, expression) =>
{
return query.Include(expression);
};
List<Models.Campaign> allResults = null;
using (var sut = new CampaignRepository(_moqContext.Object, includeMethod))
{
allResults = sut.AllIncluding(o => o.Id, o => o.Name).OrderBy(o => o.Id).ToList();
}
However this pattern also ends the same way, the IQueryable<Campaign> query = _context.Campaigns;
returns the Mock type but I cant use the extension method.
Can anyone point me in the correct direction to test my repository method?
Aucun commentaire:
Enregistrer un commentaire