I'm not sure that this is possible, but I'm trying to unit test a repository that uses a DbSet. I thought the easiest solution would just be to make an Enumerable, and replace the DbSet with that, this is my attempt.
I'm using C#, EntityFramework, XUnit, and Moq
[Fact]
public void SomeTest()
{
//arrange
var mockContext = new Mock<MyDbContext>();
var mockData = new List<Person>
{
new Person { Name = "Jim", Age = 47 }
};
mockContext.Setup(db => db.Persons).Returns((DbSet<Person>)mockData.AsQueryable());
var repo = PersonRepository(mockContext.Object);
//act
var result = repo.GetByFirstName("Jim");
//assert
//do some assertion
}
The error that gets thrown is it can't convert type EnumerableQuery to a DbSet on the mockContext.Returns statement.
Here is something similar to what the interfaces look like.
PersonRepository.cs
public class PersonRepository: EFRepository<Person>, IPersonRepository
{
public PersonRepository(DbContext dbContext) : base(dbContext)
{
}
public IQueryable<Link> GetByFirstName(string name)
{
return DbSet.Where(p => p.FirstName == name);
}
}
IPersonRepository.cs
public interface IPersonRepository: IRepository<Person>
{
IQueryable<Person> GetByFirstName(string name);
}
IRepository.cs
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Delete(T entity);
void Delete(int id);
void Update(T entity);
}
EFRepository.cs
public class EFRepository<T> : IRepository<T> where T : class
{
protected DbContext DbContext { get; set; }
public IDbSet<T> DbSet { get; set; }
public EFRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
...
}
What you can do is to move the Linq expression from your repository into the business logic and mock the repository instead.
Now rewrite your test to validate the business logic.