Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing: Entity Framework by faking context

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

like image 336
Ibsonic Avatar asked May 22 '13 14:05

Ibsonic


2 Answers

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.

like image 195
Liel Avatar answered Sep 28 '22 07:09

Liel


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.

like image 22
Sunny Milenov Avatar answered Sep 28 '22 05:09

Sunny Milenov