#region License
/*
* Copyright 2002-2008 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 NHibernate;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Transaction.Support;
#endregion
namespace Spring.Data.NHibernate.Support{
/// <summary>
/// Tests for SessionScope
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class SessionScopeTests
{
private MockRepository repository;
private ISessionFactory expectedSessionFactory;
private IInterceptor expectedEntityInterceptor;
private bool expectedSingleSession;
private FlushMode expectedDefaultFlushMode;
[SetUp]
public void SetUp()
{
repository = new MockRepository();
expectedSessionFactory = (ISessionFactory)repository.CreateMock(typeof(ISessionFactory));
expectedEntityInterceptor = (IInterceptor)repository.CreateMock(typeof(IInterceptor));
expectedSingleSession = SessionScopeSettings.SINGLESESSION_DEFAULT;
expectedDefaultFlushMode = SessionScopeSettings.FLUSHMODE_DEFAULT;
}
[Test]
public void CanCreateAndClose()
{
using (SessionScope scope = new SessionScope(expectedSessionFactory, expectedEntityInterceptor, expectedSingleSession, expectedDefaultFlushMode, false))
{
// no op - just create & dispose
Assert.AreSame(expectedSessionFactory, scope.SessionFactory);
Assert.AreSame(expectedEntityInterceptor, scope.EntityInterceptor);
Assert.AreEqual(expectedSingleSession, scope.SingleSession);
Assert.AreEqual(expectedDefaultFlushMode, scope.DefaultFlushMode);
// ensure nothing got registered with TSM
Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
scope.Close();
}
}
[Test]
public void CanCreateAndCloseSimpleCtor()
{
using (repository.Ordered())
{
ISession session = (ISession) repository.CreateMock(typeof (ISession));
Expect.Call(expectedSessionFactory.OpenSession()).Return(session);
session.FlushMode = FlushMode.Never;
Expect.Call(session.Close()).Return(null);
}
repository.ReplayAll();
using (SessionScope scope = new SessionScope(expectedSessionFactory, true))
{
// no op - just create & dispose
Assert.AreSame(expectedSessionFactory, scope.SessionFactory);
//Assert.AreSame(null, scope.EntityInterceptor);
Assert.AreEqual(expectedSingleSession, scope.SingleSession);
Assert.AreEqual(expectedDefaultFlushMode, scope.DefaultFlushMode);
// ensure SessionHolder object is registered with TSM
Assert.IsTrue(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.GetResource(expectedSessionFactory);
// by default session is lazy, so ask for it.
Assert.IsNotNull(sessionHolder.Session);
scope.Close();
}
repository.VerifyAll();
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void OpeningTwiceThrowsInvalidOperationException()
{
using (SessionScope scope = new SessionScope(expectedSessionFactory, true))
{
scope.Open();
}
}
[Test]
public void ClosingTwiceIsIgnored()
{
using (SessionScope scope = new SessionScope(expectedSessionFactory, true))
{
scope.Close();
scope.Close();
}
}
[Test]
public void DisposeClosesScope()
{
SessionScope scope = new SessionScope(expectedSessionFactory, true);
Assert.IsTrue(scope.IsOpen);
scope.Dispose();
Assert.IsFalse(scope.IsOpen);
}
[Test]
public void DoesOpenImmediatelyOnOpenIsTrue()
{
SessionScope scope = null;
using (scope = new SessionScope(expectedSessionFactory, true))
{
// ensure is open
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
scope.Close();
// ensure is closed
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
}
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
using (scope = new SessionScope(expectedSessionFactory, true))
{
// ensure is open
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
}
// ensure dispose closes scope
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
}
[Test]
public void DoesNotOpenImmediatelyOnOpenIsFalse()
{
SessionScope scope = null;
using (scope = new SessionScope(expectedSessionFactory, false))
{
// ensure is *not* open
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
scope.Open();
// ensure is open now
Assert.IsTrue(scope.IsOpen);
scope.Close();
// ensure is closed
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
}
// ensure is closed
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
}
[Test]
public void SingleSessionRegistersSessionHolderWithTSM()
{
SessionScope scope = null;
using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
{
// ensure is open
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
// ensure registered sessionholder with TSM
Assert.IsTrue(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
// ensure a sessionHolder is registered
SessionHolder sessionHolder = TransactionSynchronizationManager.GetResource(expectedSessionFactory) as SessionHolder;
Assert.IsNotNull(sessionHolder);
}
// ensure scope is closed and sessionHolder is unregistered from TSM
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
}
[Test]
public void SingleSessionAppliesDefaultFlushModeOnOpenSessionAndClosesSession()
{
ISession expectedSession = (ISession)repository.CreateMock(typeof(ISession));
Expect.Call(expectedSessionFactory.OpenSession()).Return(expectedSession);
expectedSession.FlushMode = FlushMode.Auto;
Expect.Call(expectedSession.Close()).Return(null);
repository.ReplayAll();
SessionScope scope = null;
using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
{
SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(expectedSessionFactory);
Assert.IsTrue(sessionHolder.ContainsSession(expectedSession));
}
// ensure scope is closed and sessionHolder is unregistered from TSM
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
repository.VerifyAll();
}
[Test]
public void SingleSessionNestedSessionParticipatesInParentScopeSessionFactory()
{
SessionScope scope = null;
using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
{
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
using (SessionScope innerScope = new SessionScope(expectedSessionFactory, true))
{
// outer scope didn't change
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
// participating only - no SessionHolder will be registered!
Assert.IsTrue(innerScope.IsOpen);
Assert.IsTrue(innerScope.IsParticipating);
innerScope.Close();
Assert.IsFalse(innerScope.IsOpen);
Assert.IsFalse(innerScope.IsParticipating);
// outer scope didn't change
Assert.IsTrue(scope.IsOpen);
Assert.IsFalse(scope.IsParticipating);
Assert.IsTrue(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
}
}
// ensure scope is closed and sessionHolder is unregistered from TSM
Assert.IsFalse(scope.IsOpen);
Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
}
public class TestSessionScopeSettings : SessionScopeSettings
{
public TestSessionScopeSettings(ISessionFactory sessionFactory)
: base(sessionFactory)
{
}
protected override IInterceptor ResolveEntityInterceptor()
{
return DoResolveEntityInterceptor();
}
public virtual IInterceptor DoResolveEntityInterceptor()
{
return base.ResolveEntityInterceptor();
}
}
[Test]
public void ResolvesEntityInterceptorOnEachOpen()
{
TestSessionScopeSettings sss =
(TestSessionScopeSettings)repository.PartialMock(typeof(TestSessionScopeSettings), expectedSessionFactory);
ISession expectedSession = (ISession)repository.CreateMock(typeof(ISession));
sss.DefaultFlushMode = FlushMode.Never;
SessionScope sc = new SessionScope(sss, false);
using (repository.Ordered())
{
Expect.Call(sss.DoResolveEntityInterceptor()).Return(expectedEntityInterceptor);
Expect.Call(expectedSessionFactory.OpenSession(expectedEntityInterceptor)).Return(expectedSession);
expectedSession.FlushMode = FlushMode.Never;
Expect.Call(expectedSession.Close()).Return(null);
Expect.Call(sss.DoResolveEntityInterceptor()).Return(expectedEntityInterceptor);
Expect.Call(expectedSessionFactory.OpenSession(expectedEntityInterceptor)).Return(expectedSession);
expectedSession.FlushMode = FlushMode.Never;
Expect.Call(expectedSession.Close()).Return(null);
}
repository.ReplayAll();
sc.Open();
SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(expectedSessionFactory);
sessionHolder.ContainsSession(null); // force opening session
sc.Close();
sc.Open();
sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(expectedSessionFactory);
sessionHolder.ContainsSession(null); // force opening session
sc.Close();
repository.VerifyAll();
}
}
}
|