Reputation: 167
I have developed a MVC Application with Entity Framework[DB]. I have processed CRUD Operation directly on entity without using Repository ORM.
Now I planned to write unit testing.
Is it possible to mock entities without using my Production Database?
Please suggest best way to mock entities
Upvotes: 1
Views: 762
Reputation: 2368
One possible way is to wrap the existing Entity Framework classes in an interface. So for example you could create an interface called IDbContextAdapter
and implement a class called DbContextAdapter
. This would then implement the interface and simply relay calls onto a real DbContext
.
public interface IDbContextAdapter
{
IEnumerable<DbEntityValidationResult> GetValidationErrors();
int SaveChanges();
...
}
Then the class...
public class DbContextAdapter : IDbContextAdapter
{
private readonly DbContext _realContext;
public DbContextAdapter(DbContext context)
{
_realContext = context;
}
public IEnumerable<DbEntityValidationResult> GetValidationErrors()
{
return _realContext.GetValidationErrors();
}
public int SaveChanges()
{
_realContext.SaveChanges();
}
}
Now you can use IDbContextAdapter
throughout your code and you can mock the interface during testing. You can do this for each Entity Framework class that makes external calls and it also allows you to add extra error checking, etc, whenever you use a DbContext
method.
I have used this approach with Azure Table/Queue Storage and it work well, but requires extra coding in order to wrap the real objects.
UPDATE #1: As a side note I wouldn't wrap all of the EF objects. instead, just those that access external resources. So if I method has a parameter that is a type EF object and this object simply has a few properties, then include that in your IDbContextAdapter
method signature and don't bother wrapping it (this also applies to return values).
UPDATE #2: Updated the code samples to illustrate the points in UPDATE #1. Notice how the GetValidationErrors
method doesn't bother wrapping the EF type DbEntityValidationResult
, but instead simply returns the actual object returned from the real DbContext
.
Upvotes: 3