2014-01-11 11 views
5

私はJustMockを使用してEntity Framework 6.0.2非同期メソッドをモックしようとしています。私はtesting with async queriesを次のですが、それは私がMock Multiple Interfacesの助けを借りてJustMockにこれを変換しようとしているが、例外を取得しています部品番号を使用して記述している:JustMockを使ってEF 6非同期メソッドをモックする方法は?

ソースのプロバイダのIQueryableは IDbAsyncQueryProviderを実装していません。 IDbAsyncQueryProviderを実装するプロバイダーのみが、Entity Framework非同期操作 の操作に使用できます。詳細は http://go.microsoft.com/fwlink/?LinkId=287068を参照してください。ここで

私のコードです:

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

テスト:

[Fact] 
public async Task DbTest() 
{ 
    var data = await baseRepository.FindAsync(1); 
    Assert.NotEqual(null, data); 
} 

リポジトリ:

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

インタフェース:

public interface IDbContext 
{ 
    DbSet<T> Set<T>() where T : class; 
} 

コンテキスト:

public class TimeSketchContext : DbContext, IDbContext 
{ 
    public virtual DbSet<EmployeeSkill> EmployeeSkill { get; set; } 
} 
+0

サンプルコードをありがとう。私は今、私のテストを受けました。 –

答えて

2

JustMockはあなたが

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

を書いているとき、それはあなたが例外を取得DbContext.Set<>ではなく、あなたのIDbContext.Set<>を模擬します非仮想メソッドを模擬することができますので。

あり、これに少なくとも2溶液:

  • モックあなたIDbContextインターフェース

    var mockContext = Mock.Create<IDbContext>(); 
    
  • またはその代わりに、あなたのインターフェースのDbContext使用するようにBaseRepositoryをバックに変更:

    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); 
        } 
    } 
    
関連する問題