Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking DbSet<T> inline

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.

like image 238
Matas Vaitkevicius Avatar asked Apr 17 '26 11:04

Matas Vaitkevicius


1 Answers

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.

like image 121
silleknarf Avatar answered Apr 19 '26 01:04

silleknarf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!