I am writing a lot of unit tests and due to the specifics of our framework, each one needs this mock which uses DbSet and some type. The only difference is the type, so I would like to avoid repeating the same method many times and if possible have one (maybe) generic method.
Using EF 6, .Net 4.7.1
Here is what I have now:
private Mock<DbSet<MyClass>> MockSetupForDbSet(List<MyClass> expected)
{
var mockDbSet = new Mock<DbSet<MyClass>>();
mockDbSet.As<IQueryable<MyClass>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<MyClass>(expected.AsQueryable().Provider));
mockDbSet.As<IQueryable<MyClass>>().Setup(m => m.Expression).Returns(expected.AsQueryable().Expression);
return mockDbSet;
}
And this is what I need:
private Mock<DbSet<T>> MockSetupForDbSet(List<T> expected) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.As<IQueryable<T>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<T>(expected.AsQueryable().Provider));
mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(expected.AsQueryable().Expression);
return mockDbSet;
}
Is this the proper way or should I use another approach, e.g. dynamic parameter?
----- EDIT -----
Here is the final version of the generic method, thanks to the help from StackOverflow members (in case it helps someone in future):
internal static Mock<DbSet<T>> MockSetupForDbSet<T>(List<T> expected) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.As<IQueryable<T>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<T>(expected.AsQueryable().Provider));
mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(expected.AsQueryable().ElementType);
mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(expected.AsQueryable().GetEnumerator());
mockDbSet.As<IDbAsyncEnumerable<T>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<T>(expected.GetEnumerator()));
mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(expected.AsQueryable().Expression);
return mockDbSet;
}
The test is written based and depends on Microsoft documentation 'Testing with a mocking framework": https://learn.microsoft.com/en-us/ef/ef6/fundamentals/testing/mocking#async
Include the generic type argument
This
|
V
Mock<DbSet<T>> MockSetupForDbSet<T>(List<T> expected) where T : class {
//...omitted for brevity
}
provided the function is not already part of a generic class
class MyClass<T> {
Mock<DbSet<T>> MockSetupForDbSet(List<T> expected) where T : class {
//...omitted for brevity
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With