Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

Entity Framework: Automated Testing

Build Automated Tests for EF-dependent code


Julie Lerman
thedatafarm.com/blog

Goals

Automated Testing Overview


Testing Database Interaction
Testing Entity Framework Integration with your logic
Avoiding EF and the DB with Fakes
Resources

Automated Testing

Unit
Testing

Integration
Testing

System
Testing
Interaction
User Interface Testing
Testing

Testing Code that Interacts with the Database

My Business Logic
Adds some data to
the database

My Concern
Does it really work?

My Test
Run the method
Query the database
to see if the data is
really there

But
is it really
a unit test?

Unit Testing when EF Intrudes

public List<Order> OrdersFromAPromotion(Promotion promo)


{
if (promo.StartDate<=DateTime.Today)
{
return _context.Orders
.Where(o => o.PromotionId == promo.PromotionId)
.ToList();
}
return null;
}

Testing for Both Responses


[TestMethod]
public void
GetOrdersForFuturePromotionsSkipsQueryAndReturnsNull()
[TestMethod]
public void GetOrdersForPastPromotionsDoesNotSkipQuery()

Unit Testing when EF Intrudes

public List<Order> OrdersViaPromotion(Promotion promo)


{
if (promo.StartDate<=DateTime.Today)
{
return _context.Orders
.Where(o => o.PromotionId == promo.PromotionId)
.ToList();
}
return null;
}

EF Context
& Database

Unit Testing when EF Intrudes

public List<Order> OrdersViaPromotion(Promotion promo)


{
if (promo.StartDate<=DateTime.Today)
{
return _context.Orders
.Where(o => o.PromotionId == promo.PromotionId)
.ToList();
}
return null;
}

Fake Context
& Fake Data

Step 1: Abstracting DbSet


System.Data.Entity.

IDbSet

System.Data.Entity.DbSet

MyCustom FakeDbSet
: IDbSet

Adding in a Fake IDbSet Implementation

1. Create abstract FakeDbSet : IDbSet

Note abstract Find method

2. Derive FakeDbSet

PromotionFakeDbSet

3. Prep existing context classes*

SalesContext

Step 1: Abstracting ObjectSet


System.Data.Entity.

IObjectSet
System.Data.Entity.ObjectSet

MyCustom FakeObjectSet
: IObjectSet

Step 2: and then Abstracting the Context


IContext
My custom

ISalesContext

Fake
SalesContext

SalesContext
:DbContext
:ISalesContext

(No pre-defined DbSets)

IDbSet(Customer)
IDbSet(Order)
DbSet(Customer) IDbSet() FakeDbSet(Customer) :ISalesContext
DbSet(Order)
FakeDbSet(Order)
DbSet()
FakeDbSet()

UOW/Repository
takes
ISalesContext

IUow

needs
IContext

Abstractions & Their Interactions

IRepository

IUnitofWork<TContext>

IContext
IDbSet

SalesRepository
UoW<SalesContext>

CustomerRepository

SalesContext

UoW<CustSvcContext>

DbSet<Order>
DbSet < >

SalesRepository
UoW<FakeSalesContext>

FakeSalesContext
FakeOrderDbSet
FakexxDbSet

CustSvcContext
DbSet<Customer>
DbSet < >

Layers, Layers & More Layers


IContext

IModelContext

IDbSet(class A)

System.Data.Entity.

IDbSet

abstract
FakeDbSet<T>

IDbSet(classB)

ModelContext

IDbSet(class A)
IDbSet(classB)

FakeModelContext

IDbSet(class A)
IDbSet(classB)

ClassFakeDbSet
:FakeDbSet<Class>
IEntityRepository<T>

IUnitOfWork

IClassRepository

:IEntityRepository<Class>
UnitOfWork<ConcreteContext>

ClassRepository

: IClassRepository

Getting EF Out of the Way

Fake
DbSet
Fake
Context B

Tests

Classes
Classes
Classes
Classes

System.Data
.Entity
Metadata &
DbContext

ositories
ositories
ositories
Repositories
Unit of Work

UI

Unit Testing when EF Intrudes

public List<Order> OrdersViaPromotion(Promotion promo)


{
if (promo.StartDate<=DateTime.Today)
{
return _context.Orders
.Where(o => o.PromotionId == promo.PromotionId)
.ToList();
}
return null;
}

Over-Abstracting the DbContext or DbSet?

IContext
?
?
?

FakeDbSet
?
?
?

Summary

Resources
My books

Programming Entity Framework


Programming Entity Framework: Code First
Programming Entity Framework: DbContext

My website & blogs:

thedatafarm.com (mentoring)
thedatafarm.com/blog, learnentityframework.com

Entity Framework Team: blogs.msdn.com/adonet


Domain Driven Design Starting Point: www.domaindrivendesign.org
More EF, Patterns & Testing Videos:

Pluralsight On-Demand Training: pluralsight.com

MSDN Developer Center: msdn.com/data/ef

You might also like