How to mock EF 6 Async methods using JustMock?

.net, asynchronous, c#, entity-framework, moq

Solution

Because JustMock can mock non virtual methods when you are writing

var mockContext = Mock.Create<TimeSketchContext>();
mockContext.Arrange(x => x.Set<EmployeeSkill>()).Returns(mockSet);

it will mock the `DbContext.Set<>` and not your `IDbContext.Set<>` so you get the exception.

There are at least 2 solution to this:

Mock your `IDbContext` interface

var mockContext = Mock.Create<IDbContext>();

Or change back your `BaseRepository` to use a `DbContext` instead of your interface:

public class BaseRepository<T> : IRepositoryBase<T> where T : class, IEntity, new()
{
    protected readonly DbContext InnerDbContext;
    protected DbSet<T> InnerDbSet;

    public BaseRepository(DbContext innerDbContext)
    {
        InnerDbContext = innerDbContext;
        InnerDbSet = InnerDbContext.Set<T>();
    }

    public virtual Task<T> FindAsync(long id)
    {
        return InnerDbSet.FirstOrDefaultAsync(x => x.Id == id);
    }
}  

Problem

I am trying to Mock Entity Framework 6.0.2 Async methods using JustMock. I am following testing with async queries but it is write using Moq I am trying to convert this into JustMock with help of Mock Multiple Interfaces but getting an exception : The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider. Only providers that implement IDbAsyncQueryProvider can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068. Here is my code : ``` var dummyData = GetEmployeeSkills(); var mockSet = Mock.Create<DbSet<EmployeeSkill>>(); (mockSet as IDbAsyncEnumerable<EmployeeSkill>).Arrange(x => x.GetAsyncEnumerator()) .Returns(new TestDbAsyncEnumerator<EmployeeSkill>(dummyData.GetEnumerator())); (mockSet as IQueryable<EmployeeSkill>).Arrange(x => x.Provider).Returns(new TestDbAsyncQueryProvider<EmployeeSkill>(dummyData.Provider)); (mockSet as IQueryable<EmployeeSkill>).Arrange(x => x.Expression).Returns(dummyData.Expression); (mockSet as IQueryable<EmployeeSkill>).Arrange(x => x.ElementType).Returns(dummyData.ElementType); (mockSet as IQueryable<EmployeeSkill>).Arrange(x => x.GetEnumerator()).Returns(dummyData.GetEnumerator()); var mockContext = Mock.Create<TimeSketchContext>(); mockContext.Arrange(x => x.Set<EmployeeSkill>()).Returns(mockSet); baseRepository = new BaseRepository<EmployeeSkill>(mockContext); private EmployeeSkill GetEmployeeSkill() { return new EmployeeSkill { SkillDescription = "SkillDescription", SkillName = "SkillName", Id = 1 }; } private IQueryable<EmployeeSkill> GetEmployeeSkills() { return new List<EmployeeSkill> { GetEmployeeSkill(), GetEmployeeSkill(), GetEmployeeSkill(), }.AsQueryable(); } ``` Test : ``` [Fact] public async Task DbTest() { var data = await baseRepository.FindAsync(1); Assert.NotEqual(null, data); } ``` Repository : ``` public class BaseRepository<T> : IRepositoryBase<T> where T : class, IEntity, new() { protected readonly DbContext InnerDbContext; protected DbSet<T> InnerDbSet; public BaseRepository(IDbContext innerDbContext) { InnerDbContext = innerDbContext as DbContext; InnerDbSet = innerDbContext.Set<T>(); } public virtual Task<T> FindAsync(long id) { return InnerDbSet.FirstOrDefaultAsync(x=>x.Id == id); } } ``` Interface : ``` public interface IDbContext { DbSet<T> Set<T>() where T : class; } ``` Context : ``` public class TimeSketchContext : DbContext, IDbContext { public virtual DbSet<EmployeeSkill> EmployeeSkill { get; set; } } ```

Original source