Unit Testing the Use of TransactionScope
- by Randolpho
The preamble:
I have designed a strongly interfaced and fully mockable data layer class that expects the business layer to create a TransactionScope when multiple calls should be included in a single transaction.
The problem: I would like to unit test that my business layer makes use of a TransactionScope object when I expect it to.
Unfortunately, the standard pattern for using TransactionScope is a follows:
using(var scope = new TransactionScope())
{
// transactional methods
datalayer.InsertFoo();
datalayer.InsertBar();
scope.Complete();
}
While this is a really great pattern in terms of usability for the programmer, testing that it's done seems... unpossible to me. I cannot detect that a transient object has been instantiated, let alone mock it to determine that a method was called on it. Yet my goal for coverage implies that I must.
The Question: How can I go about building unit tests that ensure TransactionScope is used appropriately according to the standard pattern?
Final Thoughts: I've considered a solution that would certainly provide the coverage I need, but have rejected it as overly complex and not conforming to the standard TransactionScope pattern. It involves adding a CreateTransactionScope method on my data layer object that returns an instance of TransactionScope. But because TransactionScope contains constructor logic and non-virtual methods and is therefore difficult if not impossible to mock, CreateTransactionScope would return an instance of DataLayerTransactionScope which would be a mockable facade into TransactionScope.
While this might do the job it's complex and I would prefer to use the standard pattern. Is there a better way?