Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing and Entity Framework

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)

like image 219
neel Avatar asked Oct 10 '13 04:10

neel


People also ask

Which framework is used for unit testing?

JUnit is an open source framework you can use to write and run tests. It aims to help develop bug-free and reliable code written in Java. JUnit provides test runners that run tests and assertions to test the expected results.

Is unit testing a framework?

What are unit test frameworks and how are they used? Simply stated, they are software tools to support writing and running unit tests, including a foundation on which to build tests and the functionality to execute the tests and report their results.

How does EF core help unit testing?

Testing EF Core Applications Testing is an important concern to almost all application types - it allows you to be sure your application works correctly, and makes it instantly known if its behavior regresses in the future.

What is unit testing in .NET core?

In this chapter, we will discuss how to create a Testing project using . NET Core. Unit testing is a development process for the software that has the smallest testable parts of an application, which are called units.


3 Answers

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.

like image 169
sunil Avatar answered Sep 30 '22 22:09

sunil


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.

like image 31
TGH Avatar answered Sep 30 '22 21:09

TGH


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.

like image 38
Thilina H Avatar answered Sep 30 '22 22:09

Thilina H