7

I am eating myself up at this moment. It is like Entity Framework isn't testable. I've read alot of posts and threads where they use unit of work or moq or the repo pattern.

I am in a phase that i can't change alot of my architechture of my application. The application fully works at this moment but to be sure I need to have a high code coverage, so testing it is.

For testing, I am using the 'fake context' method where I can use the fake one for mocking and the real one for connection to the database.

I used this as an example. http://romiller.com/2010/09/07/ef-ctp4-tips-tricks-testing-with-fake-dbcontext/

There, you can see that the context is splitted and used as an interface. Like:

    public interface IEmployeeContext
    {
        IDbSet Department Departments { get; }
        IDbSet Employee Employees { get; }
        int SaveChanges();
    }

    public class EmployeeContext : DbContext, IEmployeeContext
    {
        public IDbSet Department Departments { get; set; }
        public IDbSet Employee Employees { get; set; }
    }

    public class FakeEmployeeContext : IEmployeeContext
    {
        public FakeEmployeeContext()
        {
            this.Departments = new FakeDepartmentSet();
            this.Employees = new FakeEmployeeSet();
        }

        public IDbSet Department Departments { get; private set; }

        public IDbSet Employee Employees { get; private set; }

        public int SaveChanges()
        { 
         return 0; 
        }
    }

    }

So tesing and everything works. The only thing i can't seem to do, is test a controller with .State in it where i check whether it's changed Like: EntityState.Modified

Because this uses an interface I need to add that into the interface context. And create a new one. Or am I missing something ? It is likely not the intention that I create the whole method in that context.. How can I manage to get this to work

tereško
  • 58,060
  • 25
  • 98
  • 150
Ibsonic
  • 203
  • 3
  • 10

3 Answers3

4

Have you considered performing integration tests instead?

You can have integration tests against a real EF DBContext, just give it a different connection string in the App.config of the unit-tests project.

Read this and all of the answers to it.

Community
  • 1
  • 1
Liel
  • 2,407
  • 4
  • 20
  • 39
  • So basically I will test against a real fake database of visual studio itself? – Ibsonic May 23 '13 at 06:52
  • Integration test it is ! Thanks @Liel this helped me alot. I reverted my contexts back.. The beauty of this is that is completely seperated instead of creating fake contexts which is just unneeded code. – Ibsonic May 23 '13 at 08:23
1

Just add the property in the context interface. Btw, you don't need the FakeContext, you can just create a mock of the interface, and setup the properties to return your fake datasets. That way, you can add/remove as many methods and properties in the interface, as you need.

Sunny Milenov
  • 21,990
  • 6
  • 80
  • 106
  • Whenever I add that property in my interface, I also need to define it in the context who are inherited of the interface.. Which means I need to write the method all over again? – Ibsonic May 23 '13 at 06:51
1

Thanks to @Liel I managed to get this work. creating a 'test' db for integration testing.. instead of using unnecesary code in my opinion. My project is now fully independend by using this method.

[TestInitialize]
public void InitializBeforeTests()
{
    AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""));
    Database.SetInitializer<DataAccess.DataContext>(new DropCreateDatabaseAlways<DataAccess.DataContext>());
    var context = new DataAccess.DataContext();
    context.Database.Initialize(force: true);
}

and creating a new connection string in my test project in APP.Config.

Thanks all for your answers !

Ibsonic
  • 203
  • 3
  • 10