We're using Effort.EF6 to build a test suite for an ASP.NET Web API 2 service working against an in-memory database, and for the most part it's a wonderful experience.
However, for reasons unrelated to this question, we have had to turn off lazy loading in EF6 (by running Configuration.LazyLoadingEnabled = false;
in the constructor of the db context), which means that if we forget to .Include()
a relation somewhere and later use it, we get NullReferenceExceptions
. We'd like our tests to catch these types of errors.
Our test setup is basically as follows:
The problem is we can't figure out how to configure Effort.EF6 to disallow lazy loading, since it seems that anything we've added to the context in our test setup is already loaded when the code under test runs, and thus we never see the exceptions. We're assuming this is because we're re-using the context instance between test setup and actual code execution.
If we try to switch the third step to the following:
we instead end up with an empty db context, i.e. it has no data despite us adding a few data points before running the test.
How can we construct and inject a db context using Effort, which will fail if the .Include()
statement is missing but work if it's there?
You have to deactivate it in the constructor for Effort.EF6 too - the one that takes the DbConnection
object.
I solved it for my EF Code First project like followed:
public class MyDataContext : DbContext, IMyDataContext
{
/*
* the ohter stuff like IDbSet<T> etc.
*/
public MyDataContext() : base("name=MyConnectionString")
{
Configure();
}
/// <summary>
/// This constructor is for test usage only!
/// </summary>
/// <param name="connection">Test connection for in memory database</param>
public MyDataContext(DbConnection connection) : base(connection, true)
{
Configure();
}
/// <summary>
/// Configures the data context.
/// </summary>
private void Configure()
{
Configuration.LazyLoadingEnabled = false;
}
}
Furthermore in my test projects I am setting up test CSV files. The files will be used by Effort.EF6 to instantiate a context with seeded data. In my case I wrote a small TestDataManager that gives the possability to seed specific tables with specific files.
Here is a piece of code how you could seed data with Effort.EF6:
IDataLoader loader = new CsvDataLoader(@"C:\Temp\Test_CSV_Files");
DbConnection dbConnection = DbConnectionFactory.CreateTransient(loader);
var myDataContext = new MyDataContext(dbConnection);
Maybe this blog post could help you too.