AbstractTransactionalSpringContextTests.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Testing » Microsoft » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Testing » Microsoft » AbstractTransactionalSpringContextTests.cs
#region License

/*
 * Copyright 2002-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion


using System;
using Spring.Transaction;
using Spring.Transaction.Support;

namespace Spring.Testing.Microsoft{
    /// <summary>
    /// Convenient superclass for tests that should occur in a transaction, but normally
    /// will roll the transaction back on the completion of each test.
    /// </summary>
    /// <remarks>
    /// <p>This is useful in a range of circumstances, allowing the following benefits:</p>
    /// <ul>
    /// <li>Ability to delete or insert any data in the database, without affecting other tests</li>
    /// <li>Providing a transactional context for any code requiring a transaction</li>
    /// <li>Ability to write anything to the database without any need to clean up.</li>
    /// </ul>
    ///
    /// <p>This class is typically very fast, compared to traditional setup/teardown scripts.</p>
    ///
    /// <p>If data should be left in the database, call the <code>SetComplete()</code>
    /// method in each test. The "DefaultRollback" property, which defaults to "true",
    /// determines whether transactions will complete by default.</p>
    ///
    /// <p>It is even possible to end the transaction early; for example, to verify lazy
    /// loading behavior of an O/R mapping tool. (This is a valuable away to avoid
    /// unexpected errors when testing a web UI, for example.)  Simply call the
    /// <code>endTransaction()</code> method. Execution will then occur without a
    /// transactional context.</p>
    ///
    /// <p>The <code>StartNewTransaction()</code> method may be called after a call to
    /// <code>EndTransaction()</code> if you wish to create a new transaction, quite
    /// independent of the old transaction. The new transaction's default fate will be to
    /// roll back, unless <code>setComplete()</code> is called again during the scope of the
    /// new transaction. Any number of transactions may be created and ended in this way.
    /// The final transaction will automatically be rolled back when the test case is
    /// torn down.</p>
    ///
    /// <p>Transactional behavior requires a single object in the context implementing the
    /// IPlatformTransactionManager interface. This will be set by the superclass's
    /// Dependency Injection mechanism. If using the superclass's Field Injection mechanism,
    /// the implementation should be named "transactionManager". This mechanism allows the
    /// use of this superclass even when there's more than one transaction manager in the context.</p>
    /// 
    /// <p><i>This superclass can also be used without transaction management, if no
    /// IPlatformTransactionManager object is found in the context provided. Be careful about
    /// using this mode, as it allows the potential to permanently modify data.
    /// This mode is available only if dependency checking is turned off in
    /// the AbstractDependencyInjectionSpringContextTests superclass. The non-transactional
    /// capability is provided to enable use of the same subclass in different environments.</i></p>
    /// 
    /// </remarks>
    ///     
    /// <author>Rod Johnson</author>
    /// <author>Juergen Hoeller</author>
    /// <author>Rick Evans</author>
    /// <author>Mark Pollack (.NET)</author>
    public abstract class AbstractTransactionalSpringContextTests : AbstractDependencyInjectionSpringContextTests
    {
        /// <summary>
        /// The transaction manager to use
        /// </summary>
        protected IPlatformTransactionManager transactionManager;

        /// <summary>
        /// Should we roll back by default?
        /// </summary>
        private bool defaultRollback = true;

        /// <summary>
        /// Should we commit the current transaction?
        /// </summary>
        private bool complete = false;

        /// <summary>
        /// Number of transactions started
        /// </summary>
        private int transactionsStarted = 0;

        /// <summary>
        /// Default transaction definition is used.
        /// Subclasses can change this to cause different behaviour.
        /// </summary>
        private ITransactionDefinition transactionDefinition = new DefaultTransactionDefinition();

        /// <summary>
        /// TransactionStatus for this test. Typical subclasses won't need to use it.
        /// </summary>
        protected ITransactionStatus transactionStatus;


        /// <summary>
        /// Initializes a new instance of the <see cref="AbstractTransactionalSpringContextTests"/> class.
        /// </summary>
        public AbstractTransactionalSpringContextTests()
        {
        }

        /// <summary>
        /// Sets the transaction manager to use.
        /// </summary>
        public IPlatformTransactionManager TransactionManager
        {
            set { transactionManager = value; }
        }

        /// <summary>
        /// Sets the default rollback flag.
        /// </summary>
        public bool DefaultRollback
        {
            set { defaultRollback = value; }
        }

        /// <summary>
        /// Set the <see cref="ITransactionDefinition"/> to be used
        /// </summary>
        /// <remarks>
        /// Defaults to <see cref="DefaultTransactionDefinition"/>
        /// </remarks>
        protected ITransactionDefinition TransactionDefinition
        {
            set { transactionDefinition = value; }
        }

        /// <summary>
        /// Prevents the transaction.
        /// </summary>
        protected virtual void PreventTransaction()
        {
            this.transactionDefinition = null;
        }


        /// <summary>
        /// Creates a transaction
        /// </summary>
        protected override void OnTestInitialize()
        {
            this.complete = !this.defaultRollback;

            if (this.transactionManager == null)
            {
                logger.Info("No transaction manager set: test will NOT run within a transaction");
            }
            else if (this.transactionDefinition == null)
            {
                logger.Info("No transaction definition set: test will NOT run within a transaction");
            }
            else
            {
                OnSetUpBeforeTransaction();
                StartNewTransaction();
                try
                {
                    OnSetUpInTransaction();
                }
                catch (Exception)
                {
                    EndTransaction();
                    throw;
                }
            }
        }


        /// <summary>
        /// Callback method called before transaction is setup.
        /// </summary>
        protected virtual void OnSetUpBeforeTransaction()
        {
        }

        /// <summary>
        /// Callback method called after transaction is setup.
        /// </summary>
        protected virtual void OnSetUpInTransaction()
        {
        }

        /// <summary>
        /// rollback the transaction.
        /// </summary>
        protected override void OnTestCleanup()
        {
            // Call onTearDownInTransaction and end transaction if the transaction is still active.
            if (this.transactionStatus != null && !this.transactionStatus.Completed)
            {
                try
                {
                    OnTearDownInTransaction();
                }
                finally
                {
                    EndTransaction();
                }
            }
            // Call onTearDownAfterTransaction if there was at least one transaction,
            // even if it has been completed early through an endTransaction() call.
            if (this.transactionsStarted > 0)
            {
                OnTearDownAfterTransaction();
            }
        }

        /// <summary>
        /// Callback before rolling back the transaction.
        /// </summary>
        protected virtual void OnTearDownInTransaction()
        {
        }

        /// <summary>
        /// Callback after rolling back the transaction.
        /// </summary>
        protected virtual void OnTearDownAfterTransaction()
        {
        }

        /// <summary>
        /// Set the complete flag..
        /// </summary>
        protected virtual void SetComplete()
        {
            if (this.transactionManager == null)
            {
                throw new InvalidOperationException("No transaction manager set");
            }
            this.complete = true;
        }

        /// <summary>
        /// Ends the transaction.
        /// </summary>
        protected virtual void EndTransaction()
        {
            if (this.transactionStatus != null)
            {
                try
                {
                    if (!this.complete)
                    {
                        this.transactionManager.Rollback(this.transactionStatus);
                        logger.Info("Rolled back transaction after test execution");
                    }
                    else
                    {
                        this.transactionManager.Commit(this.transactionStatus);
                        logger.Info("Committed transaction after test execution");
                    }
                }
                finally
                {
                    this.transactionStatus = null;
                }
            }
        }

        /// <summary>
        /// Starts the new transaction.
        /// </summary>
        protected void StartNewTransaction()
        {
            if (this.transactionStatus != null)
            {
                throw new InvalidOperationException("Cannot start new transaction without ending existing transaction: " +
                                                "Invoke endTransaction() before startNewTransaction()");
            }
            if (this.transactionManager == null)
            {
                throw new InvalidOperationException("No transaction manager set");
            }

            this.transactionStatus = this.transactionManager.GetTransaction(this.transactionDefinition);
            ++this.transactionsStarted;
            this.complete = !this.defaultRollback;

            if (logger.IsInfoEnabled)
            {
                logger.Info("Began transaction (" + this.transactionsStarted + "): transaction manager [" +
                            this.transactionManager + "]; default rollback = " + this.defaultRollback);
            }
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.