2015-12-17 5 views
3

Я использую .NET4.5, EF6 и Moq для модульных испытаний. Я пытаюсь объединить некоторые данные Db для теста. У меня есть пример того, как сделать это с объявляя mockset as variable and then using mocks.Mocking DbSet <T> inline

public static class TestExtensionMethods 
{ 
     public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class 
     { 
      var queryable = sourceList.AsQueryable(); 

      var dbSet = new Mock<DbSet<T>>(); 
      dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider); 
      dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression); 
      dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType); 
      dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator()); 
      dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>(sourceList.Add); 
      return dbSet.Object; 
     } 
} 

Я использую его в качестве метода расширения ATM, как: mockedDbContext.Journey = new List<Journey> { }.AsDbSet();

есть способ объявить все это, как однострочник (так что я может передавать db-набор как TestCaseData без необходимости писать методы расширения). Я попытался следующие

var mockedDbContext = new Mock<OnlineLegal>(); 
mockedDbContext.Setup(o => o.Journey).Returns(() => (DbSet<Journey>)(new List<Journey> { new Journey { SessionId = sessionId, ConveyancingAnswer = new Collection<ConveyancingAnswer>()} }.AsEnumerable())); 

но она взрывается с System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List1[Saga.Services.Legal.Website.Journey]' to type 'System.Data.Entity.DbSet1[Saga.Services.Legal.Website.Journey]'.

Как издеваются DbSet<T> инлайн?

EDIT: В отношении к дублированию ребят, которые отмечены на мой вопрос не прикладывают усилия читать дальше, чем титул, и получите зарин от Санта в этом году.

+0

Попробуйте это http://www.loganfranken.com/blog/517/mocking-dbset-queries-in-ef6/ –

+0

@VadimMartynov Привет, спасибо за ссылку, где в статье объявляются db set inline? –

ответ

0

Используйте метод, который вы определили для создания DbSet из списка, в этом случае, когда T является типом Journey и предполагается, что o.Journey имеет тип DbSet<Journey>.

private DbSet<T> ToDbSet<T>(List<T> sourceList) where T : class 
{ 
    var queryable = sourceList.AsQueryable(); 

    var dbSet = new Mock<DbSet<T>>(); 
    dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider); 
    dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression); 
    dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType); 
    dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator()); 
    dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>(sourceList.Add); 
    return dbSet.Object; 
} 

private void SomeOtherMethod() 
{ 
    var journey = new Journey 
    { 
     SessionId = sessionId, 
     ConveyancingAnswer = new Collection<ConveyancingAnswer>() 
    }; 
    var journeys = new List<Journey> { journey }; 
    mockedDbContext.Setup(o => o.Journey) 
        .Returns(() => ToDbSet<Journey>(journeys)); 
} 

Если вы хотите поместить это на одну строку, это было бы возможно, но не обязательно желательно с точки зрения удобочитаемости.

+0

Привет, silleknarf спасибо за ответ. Где в вашем ответе можно найти DbSet, объявляемый inline, без использования методов расширения? –

+0

'TestExtensionMethods.AsDbSet (путешествия)' возвращает 'DbSet' – silleknarf

+0

Теперь я удалил использование методов расширения в своем ответе – silleknarf

Смежные вопросы