Share via


Moq Framework for unit testing Override method with SqlTransaction Parameter

Question

Monday, February 2, 2015 8:53 AM

Hello,

I have a derived class which overrides the base implementation and having SqlTransaction as parameter

Class SqlHelper

{

override Generate(SqlTransaction sqltran)

{

//some process

//Pass this to utility method for inserting record

}

}

Can some one point me how to mock SqlTransaction?

All replies (4)

Monday, February 2, 2015 11:22 AM âś…Answered

SqlTransaction is a sealed concrete class - you cannot extend it - and you won't be able to pass a mock object to Generate method if it takes an SqlTransaction object as input.

In general you would change the Generate method to accept an interface type parameter:

public interface ITransaction
{
    SqlConnection Connection {
      get;
    }
    void Commit();
    void Rollback();
    void Rollback(string transactionName);
    void Save(string savePointName);
}


override Generate(ITransaction sqltran)

You could then pass any object that implements this interface and wrap the SqlTransaction in a custom class like this:

  public sealed class SqlTransactionWrapper : ITransaction, IDisposable
  {
    SqlTransaction _tran;
    public SqlTransactionWrapper(SqlTransaction tran) {
      _tran = tran;
    }
    public SqlConnection Connection {
      get {
        return _tran.Connection;
      }
    }

    public void Commit() {
      _tran.Commit();
    }

    public void Rollback() {
      _tran.Rollback();
    }

    public void Rollback(string transactionName) {
      _tran.Rollback(transactionName);
    }

    public void Save(string savePointName) {
      _tran.Save(savePointName);
    }

    public void Dispose() {
      if (_tran != null) {
        _tran.Dispose();
        _tran = null;
      }
    }
  }


  public sealed class MockTransaction : ITransaction
  {

    public SqlConnection Connection {
      get {
        return new SqlConnection();
      }
    }

    public void Commit() {

    }

    public void Rollback() {

    }

    public void Rollback(string transactionName) {

    }

    public void Save(string savePointName) {

    }
  }

Usage:

SqlHelper helper = new SqlHelper();
      SqlTransaction tran = new SqlTransaction();
      helper.Generate(new SqlTransactionWrapper(tran));

      //mock:
      helper.Generate(new MockTransaction());

Hope that helps.

Please remember to mark helpful posts as answer to close your threads.

 


Monday, February 2, 2015 11:04 AM

I don't think you need to mock the transaction.  It doesn't contain anything useful in simulating a database.  If you right click on 'SQLTransaction' and select definition you will see the object properties.  It is used for locking the command/response from the database and for specifying the current  pointer of the data transfer. 

jdweng


Monday, February 2, 2015 11:20 AM

Then it is ok, if i create db connection and transaction properties and pass them to the unit tests?

And it that accepted practice?


Monday, February 2, 2015 11:41 AM

Hello Magnus,

Thanks. ok so i will change my base class also since the test i am trying is for derived class Override method.