Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 169135
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T12:34:36+00:00 2026-05-11T12:34:36+00:00

The preamble: I have designed a strongly interfaced and fully mockable data layer class

  • 0

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?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T12:34:36+00:00Added an answer on May 11, 2026 at 12:34 pm

    I’m just now sitting with the same problem and to me there seems to be two solutions:

    1. Don’t solve the problem.
    2. Create abstractions for the existing classes that follows the same pattern but are mockable/stubable.

    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:

    public interface ITransactionManager {     ITransaction CurrentTransaction { get; }     ITransactionScope CreateScope(TransactionScopeOption options); }  public interface ITransactionScope : IDisposable {     void Complete();   }  public interface ITransaction {     void EnlistVolatile(IEnlistmentNotification enlistmentNotification); }  public interface IEnlistment {      void Done(); }  public interface IPreparingEnlistment {     void Prepared(); }  public interface IEnlistable // The same as IEnlistmentNotification but it has                              // to be redefined since the Enlistment-class                              // has no public constructor so it's not mockable. {     void Commit(IEnlistment enlistment);     void Rollback(IEnlistment enlistment);     void Prepare(IPreparingEnlistment enlistment);     void InDoubt(IEnlistment enlistment);  } 

    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.

    public interface ITransactionManager {     ITransaction CurrentTransaction { get; }     ITransactionScope CreateScope(TransactionScopeOption options); }  public class TransactionManager : ITransactionManager {     public ITransaction CurrentTransaction     {         get { return new DefaultTransaction(Transaction.Current); }     }      public ITransactionScope CreateScope(TransactionScopeOption options)     {         return new DefaultTransactionScope(new TransactionScope());     } }  public interface ITransactionScope : IDisposable {     void Complete();   }  public class DefaultTransactionScope : ITransactionScope {     private TransactionScope scope;      public DefaultTransactionScope(TransactionScope scope)     {         this.scope = scope;     }      public void Complete()     {         this.scope.Complete();     }      public void Dispose()     {         this.scope.Dispose();     } }  public interface ITransaction {     void EnlistVolatile(Enlistable enlistmentNotification, EnlistmentOptions enlistmentOptions); }  public class DefaultTransaction : ITransaction {     private Transaction transaction;      public DefaultTransaction(Transaction transaction)     {         this.transaction = transaction;     }      public void EnlistVolatile(Enlistable enlistmentNotification, EnlistmentOptions enlistmentOptions)     {         this.transaction.EnlistVolatile(enlistmentNotification, enlistmentOptions);     } }   public interface IEnlistment {      void Done(); }  public interface IPreparingEnlistment {     void Prepared(); }  public abstract class Enlistable : IEnlistmentNotification {     public abstract void Commit(IEnlistment enlistment);     public abstract void Rollback(IEnlistment enlistment);     public abstract void Prepare(IPreparingEnlistment enlistment);     public abstract void InDoubt(IEnlistment enlistment);      void IEnlistmentNotification.Commit(Enlistment enlistment)     {         this.Commit(new DefaultEnlistment(enlistment));     }      void IEnlistmentNotification.InDoubt(Enlistment enlistment)     {         this.InDoubt(new DefaultEnlistment(enlistment));     }      void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)     {         this.Prepare(new DefaultPreparingEnlistment(preparingEnlistment));     }      void IEnlistmentNotification.Rollback(Enlistment enlistment)     {         this.Rollback(new DefaultEnlistment(enlistment));     }      private class DefaultEnlistment : IEnlistment     {         private Enlistment enlistment;          public DefaultEnlistment(Enlistment enlistment)         {             this.enlistment = enlistment;         }          public void Done()         {             this.enlistment.Done();         }     }      private class DefaultPreparingEnlistment : DefaultEnlistment, IPreparingEnlistment     {         private PreparingEnlistment enlistment;          public DefaultPreparingEnlistment(PreparingEnlistment enlistment) : base(enlistment)         {             this.enlistment = enlistment;             }          public void Prepared()         {             this.enlistment.Prepared();         }     } } 

    Here’s an example of a class that depends on the ITransactionManager to handle it’s transactional work:

    public class Foo {     private ITransactionManager transactionManager;      public Foo(ITransactionManager transactionManager)     {         this.transactionManager = transactionManager;     }      public void DoSomethingTransactional()     {         var command = new TransactionalCommand();          using (var scope = this.transactionManager.CreateScope(TransactionScopeOption.Required))         {             this.transactionManager.CurrentTransaction.EnlistVolatile(command, EnlistmentOptions.None);              command.Execute();             scope.Complete();         }     }      private class TransactionalCommand : Enlistable     {         public void Execute()         {              // Do some work here...         }          public override void Commit(IEnlistment enlistment)         {             enlistment.Done();         }          public override void Rollback(IEnlistment enlistment)         {             // Do rollback work...             enlistment.Done();         }          public override void Prepare(IPreparingEnlistment enlistment)         {             enlistment.Prepared();         }          public override void InDoubt(IEnlistment enlistment)         {             enlistment.Done();         }     } } 
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 84k
  • Answers 84k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I created the database before I added blank=True, null=True to… May 11, 2026 at 5:00 pm
  • Editorial Team
    Editorial Team added an answer Assuming there can't be random headers in the middle of… May 11, 2026 at 4:59 pm
  • Editorial Team
    Editorial Team added an answer Try Qt. Its LGPL so it can be used in… May 11, 2026 at 4:59 pm

Related Questions

Preamble: I am using ASP.NET 3.5 and AJAXControlToolkit. I am trying to use the
Preamble I'm asking this question because even though I've read through a lot of
As a fairly junior developer, I'm running into a problem that highlights my lack
A preamble: I've been using PHP for over 8 year every now and then,

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.