Some people say we shouldn’t use repository and unit of work patter because repository & UnitOfWork just duplicates what Entity Framework (EF) DbContext give you anyway. But if I use repositories I can write easy unit test for services because I can mock methods from repositories (which return data from database using linq queries), for example:
Repository:
public class CommentsRepository : ICommentsRepository
{
public CommentsRepository(DatabaseContext context)
: base(context)
{
}
public IEnumerable<Comment> GetComments()
{
return context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate).ToList();
}
}
Service:
public class CommentsService : ICommentsService
{
private ICommentsRepository _commentsRepository;
public CommentsService(ICommentsRepository commentsRepository)
{
_commentsRepository = commentsRepository;
}
public IEnumerable<Comment> GetComments()
{
List<Comment> comments = _commentsRepository.GetComments().ToList();
comments.ForEach(x => x.Author = "Secret");
return comments;
}
}
Unit test for service:
[TestClass]
public class CommentsServiceTest
{
[TestMethod]
public void GetCommentsTest()
{
// Arrange
IList<Comment> comments = Builder<Comment>.CreateListOfSize(2)
.Build();
AutoMoqer mocker = new AutoMoqer();
mocker.GetMock<ICommentsRepository>()
.Setup(x => x.GetComments())
.Returns(comments);
// Act
ICommentsService commentsService = mocker.Resolve<CommentsService>();
IList<Comment> result = commentsService.GetComments().ToList();
// Assert
Assert.AreEqual("Secret", result[0].Author);
Assert.AreEqual("Secret", result[1].Author);
}
}
Now when I eliminate repository I must write linq queries inside services:
public class CommentsService : ICommentsService
{
private DatabaseContext _context;
public CommentsService(DatabaseContext context)
{
_context = context;
}
public IEnumerable<Comment> GetComments()
{
List<Comment> comments = _context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate).ToList();
comments.ForEach(x => x.Author = "Secret");
return comments;
}
}
Writing unit test for that service is problematic because I must mock:
context.Comments.Include(x => x.Note).OrderByDescending(x => x.CreatedDate)
So what do you do? Do you write repository classes or not? If not, how do you mock linq queries?
As with all patterns, if it suits your purposes then you should use it.
I wrote a unit of work and repository pattern implementation that wrapped Entity Framework. Not only so I could do tests, but to abstract EF away from the rest of my application.
It made later switching to an in memory database for 'live' testing an absolute breeze.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With