Mocking DbSet inline

c# dbset entity-framework-6 moq unit-testing

Question

I am using .NET4.5, EF6, and Moq for unit testing. I am trying to mock up some Db data for test. I have an example how to do this with declaring mockset as variable and then using mocks.

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

I am using it as extension method ATM like: mockedDbContext.Journey = new List<Journey> { }.AsDbSet();

is there a way to declare it all as one-liner (so I could pass db sets as TestCaseData without need to write extension methods). I tried following

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

but it blows up with 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]'.

How do I mock DbSet<T> inline?

EDIT: In regards to duplication the guys who marked my question did not put effort into reading any further than title, and will get sarin gas from Santa this year.

1
3
12/17/2015 12:59:00 PM

Popular Answer

Use the method that you defined to create a DbSet from an List in this case where T is the type Journey and assuming o.Journey is of type 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));
}

If you wanted to put this on one line then it would be possible but not necessarily desirable in terms of readability.

0
12/17/2015 1:34:28 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow