I am using Entity Framework 6 and Moq framework. Currently I am writing a few Unit Tests where in each test I need to set up a dataset with the appropriate type for each test. One of the unit tests looks like this:
[TestMethod]
public async Task GetAllCaseCategories_WithEmptyDataset_ReturnsEmpty()
{
var data = new List<DataAccessLayer.Tables.CaseCategory>(){};
var mockContext = GetMockContextWithCaseCategoryDataSetAsync(data);
var mockLogger = new Mock<IDatabaseContextLogging>();
DatabaseTablesAccess databaseAccess = new DatabaseTablesAccess(mockDatabaseContext.Object, mockLogger.Object);
List<OneCaseCategory> caseCategories = await databaseAccess.GetAllCaseCategories();
Assert.IsTrue(caseCategories.Count().Equals(0), "caseCategories should not contain any items.");
}
The method that generates the database context mock object is contain in the method called "GetMockContextWithCaseCategoryDataSetAsync". Here it is:
public Mock<Context> GetMockContextWithCaseCategoryDataSetAsync(List<CaseCategory> data)
{
var mockCaseCategorySet = new Mock<DbSet<CaseCategory>>() { };
mockCaseCategorySet.As<IQueryable<CaseCategory>>().Setup(x => x.Provider).Returns(new TestDbAsyncQueryProvider<CaseCategory>(data.AsQueryable().Provider));
mockCaseCategorySet.As<IQueryable<CaseCategory>>().Setup(x => x.Expression).Returns(data.AsQueryable().Expression);
mockCaseCategorySet.As<IQueryable<CaseCategory>>().Setup(x => x.ElementType).Returns(data.AsQueryable().ElementType);
mockCaseCategorySet.As<IDbAsyncEnumerable<CaseCategory>>().Setup(x => x.GetAsyncEnumerator()).Returns(new TestDbAsyncEnumerator<CaseCategory>(data.AsQueryable().GetEnumerator()));
mockCaseCategorySet.As<IQueryable<CaseCategory>>().Setup(x => x.GetEnumerator()).Returns(data.AsQueryable().GetEnumerator());
Mock<Context> m = new Mock<Context>();
m.Setup(x => x.CaseCategories).Returns(mockCaseCategorySet.Object);
return m;
}
I have multiple tables in the data access object and I have written a method for each one that returns the data access object with the appropriate type of data bound to the correct table in the mock object. I would like to generalize this and here is my attempt:
public Mock<Context> GetMockContextWithCaseCategoryDataSetAsync<T>(List<T> data) where T : class
{
var mockCaseCategorySet = new Mock<DbSet<T>>() { };
mockCaseCategorySet.As<IQueryable<T>>().Setup(x => x.Provider).Returns(new TestDbAsyncQueryProvider<T>(data.AsQueryable().Provider));
mockCaseCategorySet.As<IQueryable<T>>().Setup(x => x.Expression).Returns(data.AsQueryable().Expression);
mockCaseCategorySet.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(data.AsQueryable().ElementType);
mockCaseCategorySet.As<IDbAsyncEnumerable<T>>().Setup(x => x.GetAsyncEnumerator()).Returns(new TestDbAsyncEnumerator<T>(data.AsQueryable().GetEnumerator()));
mockCaseCategorySet.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(data.AsQueryable().GetEnumerator());
Mock<Context> m = new Mock<Context>();
m.Setup(x => x.?).Returns(mockCaseCategorySet.Object);
return m;
}
Everything is good up until that second last line in the generic version of the method where I am setting up which table returns the mocked object. I am lost as to how (if even possible) I control which table is used based on the generic passed in. I would like to use it like this:
var context = GetMockContextWithCaseCategoryDataSetAsync<CaseCategory>(data);