CreatePersistent vs CreateTransient

Nov 8, 2013 at 9:59 PM

I've written quite a few tests with Effort against EF4 and it works well, except for one issue I'm having. My tests make use of ObjectContextFactory.CreatePersistent<T>(string, IDataLoader), as each test has a fairly large surface area and will construct multiple ObjectContext objects. They finish up with assertions on the state of the database, such as "assert that this table has 5 records".

The trouble comes when I want to run multiple tests in succession. Each test will pass individually, but because state is never "reset" assertions like "assert that this table has 5 records" will fail because the table may have already been inserted into by a previous test run.

I do have a workaround, but it's not nice. Instead of using CreatePersistent<T>, I use CreateTransient<T> and then use Reflection.Emit to construct a subtype of T which overrides the Dispose method to do nothing. This way I can pass in the same T instance into multiple classes (each of which accesses the ObjectContext with its own using block). I then Dispose of the "real" T at the end of the test run.

I think what I really need is a non-static ObjectContextFactory. Having had a quick read of the source, I realise this might be tough.

Has anybody else run into and solved it a different way? Would a non-static ObjectContextFactory be a reasonable solution?

Nov 17, 2013 at 9:56 PM
Edited Nov 17, 2013 at 9:58 PM

Sorry for late response.

Personally I do not recommend the usage of ObjectContextFactory, it serves really nice for simple applications, but on large scale it is very limiting in my opinion. I also do not recommend the usage of Persistent factory methods, because you cannot run your tests concurrently with it.

My advice is to use EntityConnectionFactory instead and pass the same fake connection instance to object contexts that are created during the same data operation.

I have written some blog posts that demonstrates how to achieve this:

And yes, this is basically a non-static ObjectContextFactory :)

This might require to redesign your application, so my second advice would be to extension of the IDbManager module:
adding methods like SetRelations(bool enabled), ClearTables, FillTables(IDataLoader loader)...etc. The DbManager can be accessed via the DbConnection object and these new methods would help to set the state of the underlying fake database. Since I do not have too much free time in the moment I would gladly accept these changes as a pull request.