Entity Framework Repository Testing : addendum
I recently posted on how to do state based testing with Repositories and the Entity Framework but failed to mention that if you are using a mocking framework like MOQ, that enforces that Mocked behaviours are required to be virtual, then that’s fine, but it’s bad practice (IMO) to leave the after effect of that lying around in the release versions of your code. Here’s an example:
var mock_repo =
new Mock<EntitiesRepository<Customer, NorthwindEntities>>
(fake_entity_model);
mock_repo
.Expect(repo => repo.AllToIList<ICustomerMakePrefered>())
.Returns(new List<Customer>()
{
new Customer()
{
CustomerID = “ALFKI”,
Country = “Germany”,
Orders = orders
},
new Customer()
{
CustomerID = “SIMSE”, Country = “Australia”
}
});
When using MOQ, this requires the Repository to have it’s AllToIList method marked with the virtual access modifier but that isn’t necessarily my intent. One way of approaching it is conditional compilation.
#if(DEBUG) public virtual IList<TEntity> AllToIList() #else public IList<TEntity> AllToIList() #endif { var entity_set_name = FindEntitySetName(); var qry = _ctx.CreateQuery<TEntity>(“[" + entity_set_name + "]“); return qry.ToList(); }
So conditional complication directives help clean up our code and make sure that any requirement in mocking is not overriding our object design intentions.
3 commentsIf you take just one thing from BDD make it this…..
In a word, NAMING! If your going to take just one thing from BDD and apply it to your work I recommend you start with the way BDD practitioners name their tests. Typically you see test names like:
[Test] public void make_customers_preferred_when_their_purchases_exceed_a_threshold() { //…….test implementation }
Even if your not using BDD I strongly suggest using the sentence like naming convention as it makes understanding what’s going on in a test library that much quicker and simpler. And, whilst your at it, why not check out BDD and give a framework like NBehave a try.
No commentsEntity Framework Repository Testing
Mark recently asked about testing the Repository / Fetching Strategy / Specification framework that I posted a while back. We can in fact bypass integration testing and by doing some state based testing on the Repository and utilise Specifications to filter the results.
[Test()] public void mock_customers_only_where_in_germany() { NorthwindEntities fake_entity_model = null; var mock_repo = new Mock<EntitiesRepository<Customer, NorthwindEntities>> (fake_entity_model); var germany_cust_spec = new Specification<Customer>(c => c.Country == “Germany”); var orders = new EntityCollection<Order>(); orders.Add(new Order{Freight = 10M}); orders.Add(new Order{Freight = 23M}); mock_repo.Expect (repo => repo.AllToIList<ICustomerMakePrefered>()) .Returns(new List<Customer>() { new Customer() { CustomerID = “ALFKI”, Country = “Germany”, Orders = orders }, new Customer() { CustomerID = “SIMSE”, Country = “Australia” } }); var results = mock_repo.Object.AllToIList<ICustomerMakePrefered>(); var cust = results.Where(germany_cust_spec.EvalFunc).First(); cust.Makeprefered(); Assert.That(cust.Orders.Sum(o => o.Freight) == 0); Assert.AreEqual(results.Count, 2); Assert.AreEqual(results.First().Country, “Germany”); Assert.AreEqual(mock_repo.Object .AllToIList<ICustomerMakePrefered>().Count, 2); }
Where the Customer Entities MakePrefered method looks like this:
public void Makeprefered() { foreach (var order in this.Orders) { order.Freight = 0M; } }
So with the help of a bit of mocking we mimic the behaviour of the database, test our business logic and all with some degree of speed improvement.
4 comments








