I have a repository that has a few private methods in to help in some general stuff that needs to be done within that repository (don't feel you need to read all the code):
public class EFBlogRepository : EFGenericRepository<Blog>, IBlogRepository
{
public EFBlogRepository( EFDbContext context )
: base( context )
{
this.context = context;
}
// Problematic method
private IQueryable<Blog> PrepareAllBlogsQuery( int page, int amount, string sort, string order, ISearchCriteria searchCriteria )
{
var query = context.Blogs
.Where( x => x.DeletedAt == null );
...
return query;
}
public IEnumerable<Blog> GetAllBlogs( int page, int amount, string sort, string order, ISearchCriteria searchCriteria )
{
return this.PrepareAllBlogsQuery( page, amount, sort, order, searchCriteria )
.Skip( ( page - 1 ) * amount )
.Take( amount );
}
public int CountAllBlogs( int page, int amount, string sort, string order, ISearchCriteria searchCriteria )
{
return this.PrepareAllBlogsQuery( page, amount, sort, order, searchCriteria )
.Count();
}
The problem comes when I try and unit test this...
I have had to make the PrepareAllBlogsQuery public
and virtual
to get this to work (You just need to read the commented bit):
// Arrange
DateTime now = DateTime.Now;
var mockDbContext = new Mock<EFDbContext>();
var blogRepository = new Mock<EFBlogRepository>(mockDbContext.Object);
IDbSet<Blog> blogDbSet = new FakeDbSet<Blog>();
List<Blog> blogs = new List<Blog> {
new Blog { BlogID = 1, Description = "1", Status = true, PublishDate = now },
new Blog { BlogID = 2, Description = "2", Status = true, PublishDate = now },
new Blog { BlogID = 3, Description = "3", Status = true, PublishDate = now },
new Blog { BlogID = 4, Description = "4", Status = true, PublishDate = now },
new Blog { BlogID = 5, Description = "5", Status = true, PublishDate = now },
new Blog { BlogID = 6, Description = "6", Status = true, PublishDate = now },
};
IQueryable<Blog> blogsQueryable = blogs.AsQueryable();
mockDbContext.SetupGet(c => c.Blogs).Returns(blogDbSet);
// This Setup requires my method to be public and virtual :(
blogRepository.SetupGet(c => c.PrepareAllBlogsQuery(2, 2, SortDirection.DESC, null, null)).Returns(blogsQueryable);
// Act
List<Blog> result = blogRepository.Object.GetAllBlogs(2, 2, SortDirection.DESC, null, null).ToList();
// Assert
Assert.AreEqual("3", result[0].Description);
Is there any way around this?
It's not like I even want to test the PrepareAllBlogsQuery
method, I just need the mock framework to know what that method returns regardless of its content.