#region License
/*
* Copyright 2002-2007 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
#region Imports
using System;
using System.Reflection;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Data;
using Spring.Objects;
#endregion
namespace Spring.Transaction.Interceptor{
/// <summary>
/// Mock object based tests for transaction aspects.
/// </summary>
/// <author>Mark Pollack</author>
[TestFixture]
public abstract class AbstractTransactionAspectTests
{
private MockRepository mocks;
[SetUp]
public void Setup()
{
mocks = new MockRepository();
}
[Test]
public void CopyAttributes()
{
IPlatformTransactionManager ptm = PlatformTxManagerForNewTransaction();
AttributesTransactionAttributeSource tas = new AttributesTransactionAttributeSource();
TestObjectMgr to = new TestObjectMgr();
ITestObjectMgr ito = (ITestObjectMgr)Advised(to, ptm, tas);
ito.DeleteTwoTestObjects("foo", "bar");
}
[Test]
public void CannotCommitTransaction()
{
ITransactionAttribute txatt = new DefaultTransactionAttribute();
MethodInfo m = typeof (ITestObject).GetMethod("GetDescription");
MethodMapTransactionAttributeSource tas = new MethodMapTransactionAttributeSource();
tas.AddTransactionalMethod(m, txatt);
IPlatformTransactionManager ptm = PlatformTxManagerForNewTransaction();
ITransactionStatus status = TransactionStatusForNewTransaction();
Expect.On(ptm).Call(ptm.GetTransaction(txatt)).Return(status);
UnexpectedRollbackException ex = new UnexpectedRollbackException("foobar", null);
ptm.Commit(status);
LastCall.On(ptm).Throw(ex);
mocks.ReplayAll();
TestObject to = new TestObject();
ITestObject ito = (ITestObject) Advised(to, ptm, tas);
try
{
ito.GetDescription();
Assert.Fail("Shouldn't have succeeded");
} catch (UnexpectedRollbackException thrown)
{
Assert.IsTrue(thrown == ex);
}
mocks.VerifyAll();
}
private IPlatformTransactionManager PlatformTxManagerForNewTransaction()
{
return (IPlatformTransactionManager) mocks.DynamicMock(typeof(IPlatformTransactionManager));
}
[Test]
public void ProgrammaticRollback()
{
ITransactionAttribute txatt = new DefaultTransactionAttribute();
MethodInfo m = typeof(RollbackTestObject).GetMethod("GetDescription");
MethodMapTransactionAttributeSource tas = new MethodMapTransactionAttributeSource();
tas.AddTransactionalMethod(m, txatt);
ITransactionStatus status = TransactionStatusForNewTransaction();
IPlatformTransactionManager ptm = PlatformTxManagerForNewTransaction();
Expect.Call(ptm.GetTransaction(txatt)).Return(status).Repeat.Once();
ptm.Commit(status);
LastCall.On(ptm).Repeat.Once();
mocks.ReplayAll();
RollbackTestObject to = new RollbackTestObject();
ITestObject ito = (ITestObject) Advised(to, ptm, tas);
Assert.AreEqual("test description", ito.GetDescription());
mocks.VerifyAll();
}
[Test]
public void RollbackOnException()
{
DoTestRollbackOnException(new Exception(), true, false);
}
[Test]
public void NoRollbackOnException()
{
DoTestRollbackOnException(new Exception(), false, false);
}
[Test]
public void RollbackOnExceptionWithRollbackException()
{
DoTestRollbackOnException(new Exception(), true, true);
}
[Test]
public void NoRollbackOnExceptionWithRollbackException()
{
DoTestRollbackOnException(new Exception(), false, true);
}
private void DoTestRollbackOnException(Exception exception, bool shouldRollback, bool rollbackException)
{
ITransactionAttribute txatt = new ConfigurableTransactionAttribute(shouldRollback);
MethodInfo mi = typeof (ITestObject).GetMethod("Exceptional");
MethodMapTransactionAttributeSource tas = new MethodMapTransactionAttributeSource();
tas.AddTransactionalMethod(mi, txatt);
ITransactionStatus status = TransactionStatusForNewTransaction();
IPlatformTransactionManager ptm =
(IPlatformTransactionManager) mocks.DynamicMock(typeof (IPlatformTransactionManager));
Expect.On(ptm).Call(ptm.GetTransaction(txatt)).Return(status);
if (shouldRollback)
{
ptm.Rollback(status);
}
else
{
ptm.Commit(status);
}
TransactionSystemException tex = new TransactionSystemException("system exception");
if (rollbackException)
{
LastCall.On(ptm).Throw(tex).Repeat.Once();
}
else
{
LastCall.On(ptm).Repeat.Once();
}
mocks.ReplayAll();
TestObject to = new TestObject();
ITestObject ito = (ITestObject) Advised(to, ptm, tas);
try
{
ito.Exceptional(exception);
Assert.Fail("Should have thrown exception");
} catch (Exception e)
{
if (rollbackException)
{
Assert.AreEqual(tex, e);
}
else
{
Assert.AreEqual(exception, e);
}
}
mocks.VerifyAll();
}
private ITransactionStatus TransactionStatusForNewTransaction()
{
return (ITransactionStatus) mocks.DynamicMock(typeof (ITransactionStatus));
}
protected abstract object Advised(object target, IPlatformTransactionManager ptm,
ITransactionAttributeSource tas);
}
internal class RollbackTestObject : TestObject
{
public override string GetDescription()
{
ITransactionStatus txStatus = TransactionInterceptor.CurrentTransactionStatus;
txStatus.SetRollbackOnly();
return "test description";
}
}
internal class ConfigurableTransactionAttribute : DefaultTransactionAttribute
{
private bool shouldRollback;
public ConfigurableTransactionAttribute(bool shouldRollback)
{
this.shouldRollback = shouldRollback;
}
public override bool RollbackOn(Exception exception)
{
return shouldRollback;
}
}
}
|