I am playing around with an MVC web app hosted on Azure using Entity Framework and SQL Server. I'm trying to set it up for unit tests and I'm using Moq to mock the DbContext and having some issues down the line. I have the following models:
class Employee
{
[Key]
public int EmployeeID{get;set;}
[ForeignKey("Business")]
public int BusinessID {get;set;}
public virtual Business {get;set;}
}
class Business
{
public Business()
{
Employees = new HashSet<Employee>();
}
[Key]
public int BusinessID{get;set;}
public virtual ICollection<Employee> Employees{get;set;}
}
Such that I can iterate all the employees of a business as well as ask a particular employee who his employer is.
So when I get down to mocking the data for tests, I mock the DbContext:
var mockContext = Mock<MyDbContext>();
and I create some test set of data:
List<Business> businesses = new List<Business>();
Business business1 = new Business();
business1.Name = "TestBusiness"
...
Then mock the DbSet for Business (so MyDbContext.Businesses is non-null):
var queryableTestData = businesses.AsQueryable();
var mockSet = new Mock<DbSet<Business>();
mockSet.As<IDbSet<Business>>().Setup(m => m.Provider).Returns(queryableTestData.Provider);
mockSet.As<IDbSet<Business>>().Setup(m => m.Expression).Returns(queryableTestData.Expression);
mockSet.As<IDbSet<Business>>().Setup(m => m.ElementType).Returns(queryableTestData.ElementType);
mockSet.As<IDbSet<Business>>().Setup(m => m.GetEnumerator()).Returns( () => queryableTestData.GetEnumerator());
mockSet.As<IDbSet<Business>>().Setup(m => m.Local).Returns( mockSet.Object.Local );
And tie it into the mock DbContext:
mockContext.Setup(context => context.Businesses).Returns(mockSet.Object);
mockContext.Setup(context => context.Set<T>()).Returns(mockSet.Object);
And I do the same thing for creating some test employee data. The problem I face is that the Business.Employees collection always returns empty even though there might be data in the collections that would normally be populated during normal operation (ie some Employee with BusinessID == 1 exists and some Business with BusinessID == 1 exists, but Business.Employees is empty only while testing).
Do I have any options other than manually establishing all entity relationships (ie: business.Employees = myTestEmployeeList.Where(e => e.BusinessID == business.BusinessID); )? I imagine this approach would be unmanagable once the object relationships are non-trivial. I'm hoping I'm doing something wrong and someone can point out my error :) Thanks for your help and time!
This is a classic issue. I think you have two options.
The downside with 2 is that it can add a decent chunk of execution time for the extra setup and configuration issues will pop up and bite you on the ass.
I personally prefer option 1.
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