Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing with Effort and SQL CE in parallel fails

I'm evaluating unit tests using EF6 in combination with

  • http://effort.codeplex.com/ and
  • SQL CE Server (Local DB file)

http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort was a quite good reference but now I'm stuck.

I have 2 test projects (one for Effort and the other for SQL CE). If I'm running both separately everthing's fine. Running both in a row with the ReSharper test runner the last test project always fails. Either

System.InvalidOperationException : The Entity Framework was already using a DbConfiguration instance before an attempt was made to add an 'Loaded' event handler. 'Loaded' event handlers can only be added as part of application start up before the Entity Framework is used.

or

System.InvalidOperationException: The default DbConfiguration instance was used by the Entity Framework before an attempt was made to set an instance of 'SqlCeConfiguration'.The 'SqlCeConfiguration' instance must be set at application start before using any Entity Framework features or must be registered in the application's config file.

It's always the same. The successor inherits the DbConfiguration instance from the predecessor. How can I run both test projects / configuration without side effects?

Here's my DbContext class:

public class DataContext : DbContext
{
    public DataContext(string connectionString) : base(connectionString)
    { Configuration.LazyLoadingEnabled = false; }

    public DataContext(DbConnection connection) : base(connection, true)
    { Configuration.LazyLoadingEnabled = false; }
}

That's the test fixture with Effort:

[TestFixtureSetUp]
public void TestFixtureSetup()
{
    EffortProviderConfiguration.RegisterProvider();
    var connection = DbConnectionFactory.CreateTransient();
    var dbContext = new DataContext(connection);
    ...
}

That's the test fixture with SQL CE:

[TestFixtureSetUp]
public void TestFixtureSetup()
{
    const string filePath = @"LocalDb.sdf";
    var connectionString = string.Format("Data Source={0}; Persist Security Info=False;", filePath);
    DbConfiguration.SetConfiguration(new SqlCeConfiguration());

    var dbContext = new DataContext(connectionString);
    dbContext.Database.Create();
    ...
}

and the my SqlCeConfiguration:

public class SqlCeConfiguration : DbConfiguration
{
    public SqlCeConfiguration()
    {
        SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance);
        SetDefaultConnectionFactory(new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0"));
    }
}

Thank you so much!

Marcel

like image 220
Marcel Avatar asked Apr 12 '14 17:04

Marcel


2 Answers

We were seeing the same errors when running all UnitTests on our build server or when running all UnitTests locally.

System.InvalidOperationException : The Entity Framework was already using a DbConfiguration instance before an attempt was made to add an 'Loaded' event handler. 'Loaded' event handlers can only be added as part of application start up before the Entity Framework is used.

Once we moved the Effort Provider registration code from the [TestInitialize] method to the AssemblyInitialize method, everything started working. Based on the message in the reported error, it appears that the registration cannot happen more than once.

    [AssemblyInitialize()]
    public static void AssemblyInit(TestContext context)
    {
        Effort.Provider.EffortProviderConfiguration.RegisterProvider();
    }
like image 131
Jeff Schreiber Avatar answered Nov 12 '22 01:11

Jeff Schreiber


I came across this just now and thought I'd share the cause of my issue.

Everything was working dandy, until I implemented and ActionFilter. It turned out that in my test the Effort code was running after the instantiation of my web site. Instantiating the web site instantiated my filter, my filter requested a DataContext from the container.

Hence someone had already made use of the datacontext before I tried to configure it with Effort.

Hope this might help someone in the future, albeit it being a bit of a different cause, and I hope you solved your issue int the end!

like image 2
Dashu Avatar answered Nov 12 '22 02:11

Dashu