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?
I’m just now sitting with the same problem and to me there seems to be two solutions:
Edit: I’ve created a CodePlex-project for this now: http://legendtransactions.codeplex.com/
I’m leaning towards creating a set of interfaces for working with transactions and a default implementation that delegates to the System.Transaction-implementations, something like:
This seems like a lot of work but on the other hand it’s reusable and it makes it all very easily testable.
Note that this is not the complete definition of the interfaces just enough to give you the big picture.
Edit: I just did some quick and dirty implementation as a proof of concept, I think this is the direction I will take, here’s what I’ve come up with so far. I’m thinking that maybe I should create a CodePlex project for this so the problem can be solved once and for all. This is not the first time I’ve run into this.
Here’s an example of a class that depends on the ITransactionManager to handle it’s transactional work: