1

I want to do unit tests for that generic repository pattern, I have tried it in various ways and I can not get it, the closest thing to do is this here I leave the implementation that I have done

    public abstract class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : Entity<TKey>
{
    private readonly ValcalContext _context;

    private readonly IUnitOfWork _unitOfWork;

    public IUnitOfWork UnitOfWork => _unitOfWork;

    public Repository(IUnitOfWork uow)
    {
        _context = uow.Context as ValcalContext;
        _unitOfWork = uow;
    }

    public List<TEntity> All => _context.Set<TEntity>().ToList();

    public List<TEntity> AllEager(params Expression<Func<TEntity, object>>[] includes)
    {
        IQueryable<TEntity> query = _context.Set<TEntity>();
        foreach (var include in includes)
        {
            query = query.Include(include);
        }
        return query.ToList();
    }

    public TEntity Find(TKey id)
    {
        return _context.Set<TEntity>().Find(id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return _context.Set<TEntity>().ToList();
    }

    public void Insert(TEntity item)
    {
        _context.Entry(item).State = EntityState.Added;
    }

    public void Delete(TEntity entity)
    {
        var item = _context.Set<TEntity>().Find(entity.Id);
        _context.Set<TEntity>().Remove(item);
    }

    public void Delete(TKey id)
    {
        var item = _context.Set<TEntity>().Find(id);
        _context.Set<TEntity>().Remove(item);
    }

    public void Update(TEntity item)
    {
        _context.Set<TEntity>().Attach(item);
        _context.Entry(item).State = EntityState.Modified;
    }

    public void Dispose()
    {
        if (_context != null)
            _context.Dispose();
    }
}

This is my dbContext

 public class ValcalContext : DbContext,IValcalContext
{
    public ValcalContext() : base("ValcalConnection")
    {
    }

    public static ValcalContext Create()
    {
        return new ValcalContext();

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        AddConventions(modelBuilder);

        var typesToRegister = TypesToRegister();

        AddConfigurationsMapping(modelBuilder, typesToRegister);

        base.OnModelCreating(modelBuilder);
    }

    #region Private Methods

    /// <summary>
    /// /Agrega las convenciones de mapeo a la base de dato
    /// </summary>
    /// <param name="modelBuilder"></param>
    private void AddConventions(DbModelBuilder modelBuilder)
    {
        modelBuilder.Types().Configure(entity => entity.ToTable(entity.ClrType.Name.ToLowerUnderscored()));
        modelBuilder.Conventions.Add(new UnderScoredLowerCaseConvention());
    }


    private static IEnumerable<Type> TypesToRegister()
    {
        var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => !string.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType
                           && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
        return typesToRegister;
    }


    private static void AddConfigurationsMapping(DbModelBuilder modelBuilder, IEnumerable<Type> typesToRegister)
    {
        foreach (var configurationInstance in typesToRegister.Select(Activator.CreateInstance))
        {
            modelBuilder.Configurations.Add((dynamic)configurationInstance);
        }
    }
    #endregion
}

I want to do unit tests for that generic repository pattern,for now I have this

    [TestClass]
public class RepositoryUnitTest
{


    [TestMethod]
    public void Sample()
    {
        //arrange
        var mockEntityTest = new Mock<DbSet<EntityTest>>();

        var unitOfWork = new  Mock<IUnitOfWork>();
        var valcalContext = new Mock<ValcalContext>();

        valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
        var mock = valcalContext.Object;

        unitOfWork.Setup(uow => uow.Context).Returns(mock);

        var repository = new RepositoryTest(unitOfWork.Object);

        //act
        var entityTests = repository.All;
        //assert
        Assert.AreEqual(entityTests.ToList().Count,0);
    }

}

 public class RepositoryTest : Repository<EntityTest, int>
{
    public RepositoryTest(IUnitOfWork uow) : base(uow)
    {
    }
}
 public  class EntityTest : Entity<int>
{

}

but I get this error

error

details error

I hope you can help me, I've been here for two hours

The member 'IEnumerable.GetEnumerator' has not been implemented on type 'DbSet1Proxy' which inherits from 'DbSet1'. Test doubles for 'DbSet`1' must provide implementations of methods and properties that are used.

This error is different from this post Moq DbSet NotImplementedException

I just tried that solution and I'm still in the same

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Johan
  • 60
  • 8

1 Answers1

1

Really what I did was the following to make it clear

  1. I uploaded the moq version for 4.8

  2. I change this

    [TestMethod]
    public void Sample()
    {
        //arrange
        var mockEntityTest = new Mock<DbSet<EntityTest>>();
    
        var unitOfWork = new  Mock<IUnitOfWork>();
        var valcalContext = new Mock<ValcalContext>();
    
        valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
        var mock = valcalContext.Object;
    
        unitOfWork.Setup(uow => uow.Context).Returns(mock);
    
        var repository = new RepositoryTest(unitOfWork.Object);
    
        //act
        var entityTests = repository.All;
        //assert
        Assert.AreEqual(entityTests.ToList().Count,0);
    }
    

for this

[TestMethod]
public void Sample()
{
    //arrange
    var mockEntityTest = new Mock<DbSet<EntityTest>>();
    var list = new List<EntityTest>();
    var queryable = list.AsQueryable();
    mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.Provider).Returns(queryable.Provider);
    mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.Expression).Returns(queryable.Expression);
    mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
    mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());

    var unitOfWork = new  Mock<IUnitOfWork>();
    var valcalContext = new Mock<ValcalContext>();

    valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
    var mock = valcalContext.Object;

    unitOfWork.Setup(uow => uow.Context).Returns(mock);

    var repository = new RepositoryTest(unitOfWork.Object);

    //act
    var entityTests = repository.All;
    //assert
    Assert.AreEqual(entityTests.ToList().Count,0);
}

and it worked, that can be done generically as explained in this post How do I go about unit testing with Entity Framework and Moq? 45558663 # 45558663

but the essence of what I did was that.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Johan
  • 60
  • 8