I'm trying to set up a mock DbSet for testing purposes. I used the tutorial here, http://www.loganfranken.com/blog/517/mocking-dbset-queries-in-ef6/ and slightly modified it so calling GetEnumerator returns a new enumerator each time (another problem i was having). However, I am having difficulty adding items to the DbSet.
The output is preCount = 3 postCount = 3. However, I expect it to be precount = 3 postCount = 4. Any help is greatly appreciated.
static void Main(string[] args) { Debug.WriteLine("hello debug"); List<string> stringList = new List<string> { "a", "b", "c" }; DbSet<string> myDbSet = GetQueryableMockDbSet(stringList); int preCount = myDbSet.Count(); myDbSet.Add("d"); int postCount = myDbSet.Count(); Debug.WriteLine("preCount = " + preCount + " postCount = " + postCount); } private static DbSet<T> GetQueryableMockDbSet<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()); return dbSet.Object; }
Unit testing is a powerful way to ensure that your code works as intended. It's a great way to combat the common “works on my machine” problem. Using Moq, you can mock out dependencies and make sure that you are testing the code in isolation.
Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.
myDbSet
is not real implementation of DbSet
but a mock which means it's fake and it needs to be setup for all methods you need. The Add
is not exception so it needs to be set up to do what you need otherwise it does nothing.
Add something like the following and when the myDbSet.Add("d");
is called then the 'd' is added to the list and can be returned later.
dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s));
private static DbSet<T> GetQueryableMockDbSet<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>((s) => sourceList.Add(s)); return dbSet.Object; }
hello debug preCount = 3 postCount = 4
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