如何使用JustMock嘲笑EF 6异步方法? [英] How to mock EF 6 Async methods using JustMock?

查看:215
本文介绍了如何使用JustMock嘲笑EF 6异步方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用JustMock模拟实体框架6.0.2异步方法。我下面测试与异步查询的,但它是用写起订量我试图将其转换成JustMock与模拟多个接口但得到一个例外:

  

该供应商源的IQueryable没有实现   IDbAsyncQueryProvider。只有实现供应商   IDbAsyncQueryProvider可用于实体框架异步   操作。详情请参阅    http://go.microsoft.com/fwlink/?LinkId=287068

下面是我的code:

  VAR dummyData = GetEmployeeSkills();
变种mockSet = Mock.Create&其中; DbSet&其中; EmployeeSkill>>();
(mockSet为IDbAsyncEnumerable< EmployeeSkill>)。安排(X => x.GetAsyncEnumerator())
         .Returns(新TestDbAsyncEnumerator&其中; EmployeeSkill>(dummyData.GetEnumerator()));

(mockSet为IQueryable的< EmployeeSkill>)。安排(X => x.Provider).Returns(新TestDbAsyncQueryProvider< EmployeeSkill>(dummyData.Provider));

(mockSet为IQueryable的< EmployeeSkill>)。安排(X => x.Ex pression).Returns(dummyData.Ex pression);
(mockSet为IQueryable的< EmployeeSkill>)。安排(X => x.ElementType).Returns(dummyData.ElementType);
(mockSet为IQueryable的< EmployeeSkill>)。安排(X => x.GetEnumerator())返回(dummyData.GetEnumerator())。

变种mockContext = Mock.Create&其中; TimeSketchContext>();
mockContext.Arrange(X => x.Set< EmployeeSkill>())返回(mockSet)。

baseRepository =新BaseRepository< EmployeeSkill>(mockContext);

私人EmployeeSkill GetEmployeeSkill()
    {
        返回新EmployeeSkill
        {
            SkillDescription =SkillDescription
            SkillName =SkillName
            ID = 1
        };
    }

    私人的IQueryable< EmployeeSkill> GetEmployeeSkills()
    {
        返回新的List< EmployeeSkill>
        {
            GetEmployeeSkill(),
            GetEmployeeSkill(),
            GetEmployeeSkill(),
        } .AsQueryable();
    }
 

测试:

  [事实]
公共异步任务DbTest()
{
   VAR数据=等待baseRepository.FindAsync(1);
   Assert.NotEqual(空,数据);
}
 

存储库:

 公共类BaseRepository< T> :IRepositoryBase< T>其中T:类,IEntity,新的()
{
    保护只读的DbContext InnerDbContext;
    保护DbSet< T> InnerDbSet;

    公共BaseRepository(IDbContext innerDbContext)
    {
        InnerDbContext = innerDbContext为的DbContext;
        InnerDbSet = innerDbContext.Set< T>();
    }

    公共虚拟任务< T> FindAsync(长ID)
    {
        返回InnerDbSet.FirstOrDefaultAsync(X => x.Id == ID);
    }
 }
 

接口:

 公共接口IDbContext
{
    DbSet< T>设置< T>()其中T:类;
}
 

上下文:

 公共类TimeSketchContext:的DbContext,IDbContext
{
    公共虚拟DbSet< EmployeeSkill> EmployeeSkill {获得;组; }
}
 

解决方案

由于JustMock可以模拟非虚方法,当你在写

  VAR mockContext = Mock.Create< TimeSketchContext>();
mockContext.Arrange(X => x.Set< EmployeeSkill>())返回(mockSet)。
 

会嘲笑 DbContext.Set<您的 IDbContext.Set&LT ,而不是;> 让你和GT得到的异常。

有至少2个解决方案是:

  • 莫克你的 IDbContext 接口

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

  • 或更改回你的 BaseRepository 使用的的DbContext ,而不是你的界面:

     公共类BaseRepository< T> :IRepositoryBase< T>其中T:类,IEntity,新的()
    {
        保护只读的DbContext InnerDbContext;
        保护DbSet< T> InnerDbSet;
    
        公共BaseRepository(的DbContext innerDbContext)
        {
            InnerDbContext = innerDbContext;
            InnerDbSet = InnerDbContext.Set< T>();
        }
    
        公共虚拟任务< T> FindAsync(长ID)
        {
            返回InnerDbSet.FirstOrDefaultAsync(X => x.Id == ID);
        }
    }
     

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; }
}

解决方案

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);
        }
    }  
    

这篇关于如何使用JustMock嘲笑EF 6异步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆