I want to mock a unit of work interface with repositories inside for unit test purpose. So far I am able to do it like below.
namespace Liquid.Service.UnitTest
{
using Liquid.DataAccess.Interface;
using Liquid.Domain;
using Domain.Interface;
using Moq;
using System.Collections.Generic;
using System.Linq;
internal class Helper
{
internal IUnitOfWork MockUnitOfWork(ICollection<Dummy> dummies = null,
ICollection<ProductType> productTypes = null)
{
dummies = dummies ?? new List<Dummy>();
productTypes = productTypes ?? new List<ProductType>();
var dummyRepositoryMock = MockDummyRepository(dummies);
var productTypeRepositoryMock = MockProductTypeRepository(productTypes);
var unitOfWorkMock = new Mock<IUnitOfWork>();
unitOfWorkMock.Setup(x => x.DummyRepository)
.Returns(dummyRepositoryMock.Object);
unitOfWorkMock.Setup(x => x.ProductTypeRepository)
.Returns(productTypeRepositoryMock.Object);
return unitOfWorkMock.Object;
}
private Mock<IDummyRepository> MockDummyRepository(ICollection<Dummy> dummies)
{
var dummyRepositoryMock = new Mock<IDummyRepository>();
dummyRepositoryMock.Setup(x => x.FindById(It.IsAny<int>()))
.Returns((int arg1) => dummies.Where(x => x.Id == arg1).SingleOrDefault());
dummyRepositoryMock.Setup(x => x.Add(It.IsAny<Dummy>()))
.Callback((Dummy arg1) => dummies.Add(arg1));
return dummyRepositoryMock;
}
private Mock<IProductTypeRepository> MockProductTypeRepository(ICollection<ProductType> productTypes)
{
var productTypeRepositoryMock = new Mock<IProductTypeRepository>();
productTypeRepositoryMock.Setup(x => x.FindById(It.IsAny<int>()))
.Returns((int arg1) => productTypes.SingleOrDefault(x => x.Id == arg1));
productTypeRepositoryMock.Setup(x => x.Add(It.IsAny<ProductType>()))
.Callback((ProductType arg1) => productTypes.Add(arg1));
return productTypeRepositoryMock;
}
}
}
You see that I've created two method to mock DummyRepository and ProductTypeRepository but because it has same implementation, I think it is redundant for every repositories I have. Below is the Repositories and IRepository code.
namespace Liquid.DataAccess.Interface
{
using Liquid.Domain;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public interface IDummyRepository : IRepository<Dummy>
{
}
public interface IProductTypeRepository : IRepository<ProductType>
{
}
public interface IRepository<TEntity> where TEntity : class
{
IList<TEntity> GetAll();
Task<List<TEntity>> GetAllAsync();
Task<List<TEntity>> GetAllAsync(CancellationToken cancellationToken);
IList<TEntity> PageAll(int skip, int take);
Task<List<TEntity>> PageAllAsync(int skip, int take);
Task<List<TEntity>> PageAllAsync(CancellationToken cancellationToken, int skip, int take);
TEntity FindById(object id);
Task<TEntity> FindByIdAsync(object id);
Task<TEntity> FindByIdAsync(CancellationToken cancellationToken, object id);
void Add(TEntity entity);
void Update(TEntity entity);
void Remove(TEntity entity);
}
}
How can I use a same method to mock every repositories implementation which inherits IRepository?
UPDATE : The test is just a simple add and check like below.
[Test]
public void ProductTypeService_Add()
{
// GIVEN
var productTypeData = new ProductType()
{
Id = 1,
Description = "ProductType1"
};
// WHEN
var unitOfWorkMock = new Helper().MockUnitOfWork();
var productTypeService = new ProductTypeService(unitOfWorkMock);
productTypeService.Add(productTypeData);
// THEN
Assert.That(productTypeService.FindById(1) != null);
}
Aucun commentaire:
Enregistrer un commentaire