11

I am very new to EF, I want to know what is the best way of creating EF with SQL Server database. After that I want to test CRUD operations. Is EF implemented in a TDD way, and I am confused by these repository patterns, mock context, fake pattern etc..

CRUD operations in EF, what all things would be tested? (DbContext, SaveChanges()... is need to test?)

So any ideas how to do unit testing with Entity Framework based components? (I am checking all these in Visual Studio 2012, ASP.NET MVC4)

4
  • 2
    Just an FYI: These are generally referred to as Integration Tests. If they were Unit Tests.. you would be hitting "Run Tests.." every 30 seconds (like you should be in TDD) and the roundtrip to the database for each test would make your tests run for minutes/hours. Integration Tests that actually integrate with other systems are run pre-release. Commented Oct 10, 2013 at 4:29
  • @SimonWhitehead: so why we use repository pattern, is that needed and what is the difference between moking and faking Commented Oct 10, 2013 at 4:33
  • After that I want to test CRUD operations You want to test your logic associated with CRUD operations, or you want to test the Entity Framework? Commented Oct 10, 2013 at 5:32
  • 2
    Unit testing the Entity Framework is not your job. Commented Oct 10, 2013 at 6:01

4 Answers 4

18

Lets say you have 2 layer solution

MyApp.Web

MyApp.Data

In your Data layer you will have something like this:

public class ProductsRepository : IProductsRepository
{
     public List<Product> GetAll()
     {
        //EF stuff 
        return _dbcontext.Products;
     }
} 

where IProductsRepository is

public interface IProductsRepository
{
   List<Product> GetAll();
}

In the MyApp.Web the trend is to do this.

public class ProductsController : Controller
{
    private readonly IProductsRepository _productsRepository;
    public ProductsController(IProductsRepository productsRepository)
    {
        _productsRepository = productsRepository;
    }

    public ActionResult Index(int page=1)
    {
        var allProducts = _productsRepository.GetAll();

        return View(allProducts)
    }
}

Who puts in ProductsRepository into the constructor at runtime? People use Dependency injection like Ninject frameworks for this. But why? Because this enables them to fake the ProductsRepository and like this

public class FakeProductsRepository : IProductsRepository
{
     public List<Product> GetAll()
     {
        return new List<Product> 
           { 
              new Product { Name = "PASTE" }
              new Product { Name = "BRUSH" } 
           }, 
     }
} 

and then UNIT TEST the controller like this

 [TestMethod]
 public void IndexGetsAllProducts()
 {
        //Arrange 
        var fakeProductRepo = new FakeProductsRepository();
        var productsController = new ProductsController(fakeProductRepo);

        //Act
        var result = productsController.Index(1) as ViewResult;

        //Assert
        var model = result.Model as List<Product>;
        Assert.AreEqual(2, model.Count);
 }

Essentially you are faking the database so the unit test is fast and independent of the database. Sometimes for faking people use a mocking framework like Moq, which essentially does the same thing.

If you want to test the ProductsRepository then it is no longer called a unit test because it depends on an external source. To test those you are essentially testing Entityframework.

In combination to unit tests people do Integration testing using frameworks like Specflow. Essentially you can instantiate the Productscontroller with the real ProductsRepository and check the results coming back.

Sign up to request clarification or add additional context in comments.

Comments

5

To test EF functionality I recommend writing integration tests against known data. A common approach is to build the data as part of the test as a precondition to your tests of your select based functionality:

Ex:

  1. Insert known data

  2. Run select functionality against known data

  3. Assert results

The above steps will test both your queries and EF bindings/model.

Business logic that acts on data returned from EF should abstract the EF logic through mocking. This will enable you to write unit tests that foucs on testing just the logic without worrying about the integration points / data dependencies.

1 Comment

just to add a possible point 4. encapsulate each test in a transaction that you roll back at the end - that way you leave your DB clean after the test run
5

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).

Just go Here for explanation with exsample.

Comments

2

You could also test your EF model with in-memory database instead. Here is an example of using Effort as database for unit tests.

1 Comment

The link is dead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.