Дописал мокирование remove, removerange, add, addrange и засунул в обобщенный метод
public static DbSet<T> MockDbSet<T>(List<T> table) where T : class
{
var dbSet = new Mock<DbSet<T>>();
dbSet.As<IQueryable<T>>().Setup(q => q.Provider).Returns(() => table.AsQueryable().Provider);
dbSet.As<IQueryable<T>>().Setup(q => q.Expression).Returns(() => table.AsQueryable().Expression);
dbSet.As<IQueryable<T>>().Setup(q => q.ElementType).Returns(() => table.AsQueryable().ElementType);
dbSet.As<IQueryable<T>>().Setup(q => q.GetEnumerator()).Returns(() => table.AsQueryable().GetEnumerator());
dbSet.Setup(set => set.Add(It.IsAny<T>())).Callback<T>(table.Add);
dbSet.Setup(set => set.AddRange(It.IsAny<IEnumerable<T>>())).Callback<IEnumerable<T>>(table.AddRange);
dbSet.Setup(set => set.Remove(It.IsAny<T>())).Callback<T>(t => table.Remove(t));
dbSet.Setup(set => set.RemoveRange(It.IsAny<IEnumerable<T>>())).Callback<IEnumerable<T>>(ts =>
{
foreach (var t in ts) { table.Remove(t); }
});
return dbSet.Object;
}
Для моих нужд пока подходит.
Объясню почему мне не нравится подход с репозиториями. Если не использовать generic репозиторий тогда код вырастет в n раз на каждую таблицу. Тогда получается надо сделать generic потом унаследовать от него каждую сущность и получается что у нас куча репозиториев. Как к ним тогда обращатся? суем их в один класс и получаем тот самый dbcontext который генерит ef а репозитории в нем это теже dbset. Тоесть мы создаем абстракцию над абстракцией чтоб смогли от неё унаследовать методы для тестов. Смысл из такого кроме очевидных минусов потери части функционала контекста я не особо вижу.