introducing generics API for ObjectFactory and Contexts

This commit is contained in:
Steve Bohlen
2011-12-14 18:55:15 -05:00
parent 94e325b438
commit 80bb9ce7c7
12 changed files with 2433 additions and 946 deletions

View File

@@ -23,32 +23,32 @@
using System;
using Common.Logging;
using Common.Logging.Simple;
using DotNetMock.Dynamic;
using NUnit.Framework;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Xml;
using Rhino.Mocks;
#endregion
namespace Spring.Aop.Target
{
/// <summary>
/// Unit tests for the PrototypeTargetSource class.
/// </summary>
/// <author>Rod Johnson</author>
/// <author>Federico Spinazzi</author>
[TestFixture]
public sealed class PrototypeTargetSourceTests
{
/// <summary>
/// The setup logic executed before the execution of this test fixture.
/// </summary>
[TestFixtureSetUp]
public void FixtureSetUp()
{
// enable (null appender) logging, just to ensure that the logging code is correct
LogManager.Adapter = new NoOpLoggerFactoryAdapter();
}
/// <summary>
/// Unit tests for the PrototypeTargetSource class.
/// </summary>
/// <author>Rod Johnson</author>
/// <author>Federico Spinazzi</author>
[TestFixture]
public sealed class PrototypeTargetSourceTests
{
/// <summary>
/// The setup logic executed before the execution of this test fixture.
/// </summary>
[TestFixtureSetUp]
public void FixtureSetUp()
{
// enable (null appender) logging, just to ensure that the logging code is correct
LogManager.Adapter = new NoOpLoggerFactoryAdapter();
}
/// <summary>
/// Test that multiple invocations of the prototype object will result
@@ -60,83 +60,106 @@ namespace Spring.Aop.Target
{
int initialCount = 10;
IObjectFactory of = new XmlObjectFactory(new ReadOnlyXmlTestResource("prototypeTargetSourceTests.xml", GetType()));
ISideEffectObject singleton = (ISideEffectObject) of.GetObject("singleton");
ISideEffectObject singleton = (ISideEffectObject)of.GetObject("singleton");
Assert.AreEqual(initialCount, singleton.Count);
singleton.doWork();
Assert.AreEqual(initialCount + 1, singleton.Count);
ISideEffectObject prototype = (ISideEffectObject) of.GetObject("prototype");
ISideEffectObject prototype = (ISideEffectObject)of.GetObject("prototype");
Assert.AreEqual(initialCount, prototype.Count);
singleton.doWork();
Assert.AreEqual(initialCount, prototype.Count);
ISideEffectObject prototypeByName = (ISideEffectObject) of.GetObject("prototypeByName");
ISideEffectObject prototypeByName = (ISideEffectObject)of.GetObject("prototypeByName");
Assert.AreEqual(initialCount, prototypeByName.Count);
singleton.doWork();
Assert.AreEqual(initialCount, prototypeByName.Count);
}
[Test]
public void TargetType()
{
SideEffectObject target = new SideEffectObject();
IDynamicMock mock = new DynamicMock(typeof (IObjectFactory));
mock.ExpectAndReturn("IsPrototype", true, null);
mock.ExpectAndReturn("GetType", typeof(SideEffectObject), null);
PrototypeTargetSource source = new PrototypeTargetSource();
source.ObjectFactory = (IObjectFactory) mock.Object;
Assert.AreEqual(target.GetType(), source.TargetType, "Wrong TargetType being returned.");
mock.Verify();
}
[Test]
public void TargetType()
{
MockRepository mocks = new MockRepository();
SideEffectObject target = new SideEffectObject();
[Test]
public void IsStatic()
{
PrototypeTargetSource source = new PrototypeTargetSource();
Assert.IsFalse(source.IsStatic, "Must not be static.");
}
IObjectFactory factory = mocks.CreateMock<IObjectFactory>();
[Test]
public void WithNonSingletonTargetObject()
{
IDynamicMock mock = new DynamicMock(typeof (IObjectFactory));
const string objectName = "Foo";
mock.ExpectAndReturn("IsPrototype", false, objectName);
PrototypeTargetSource source = new PrototypeTargetSource();
source.TargetObjectName = objectName;
try
{
source.ObjectFactory = (IObjectFactory) mock.Object;
Assert.Fail("Should have thrown an ObjectDefinitionStoreException by this point.");
}
catch (ObjectDefinitionStoreException)
{
mock.Verify();
}
}
using (mocks.Record())
{
Expect.Call(factory.IsPrototype(null)).Return(true);
Expect.Call(factory.GetType(null)).Return(typeof(SideEffectObject));
}
[Test]
public void GetTarget()
{
SideEffectObject target = new SideEffectObject();
IDynamicMock mock = new DynamicMock(typeof (IObjectFactory));;
mock.ExpectAndReturn("IsPrototype", true, "foo");
mock.ExpectAndReturn("GetObject", target, "foo");
mock.ExpectAndReturn("GetType", typeof (string), "foo");
PrototypeTargetSource source = new PrototypeTargetSource();
source.TargetObjectName = "foo";
source.ObjectFactory = (IObjectFactory) mock.Object;
Assert.IsTrue(object.ReferenceEquals(source.GetTarget(), target),
"Initial target source reference not being returned by GetTarget().");
mock.Verify();
}
using (mocks.Playback())
{
PrototypeTargetSource source = new PrototypeTargetSource();
source.ObjectFactory = factory;
Assert.AreEqual(target.GetType(), source.TargetType, "Wrong TargetType being returned.");
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void AfterPropertiesSetWithoutTargetObjectNameBeingSet()
{
PrototypeTargetSource source = new PrototypeTargetSource();
source.AfterPropertiesSet();
}
}
}
[Test]
public void IsStatic()
{
PrototypeTargetSource source = new PrototypeTargetSource();
Assert.IsFalse(source.IsStatic, "Must not be static.");
}
[Test]
public void WithNonSingletonTargetObject()
{
MockRepository mocks = new MockRepository();
IObjectFactory factory = mocks.CreateMock<IObjectFactory>();
const string objectName = "Foo";
using (mocks.Record())
{
Expect.Call(factory.IsPrototype(objectName)).Return(false);
}
using (mocks.Playback())
{
PrototypeTargetSource source = new PrototypeTargetSource();
source.TargetObjectName = objectName;
Assert.Throws<ObjectDefinitionStoreException>(delegate { source.ObjectFactory = factory; });
}
}
[Test]
public void GetTarget()
{
MockRepository mocks = new MockRepository();
IObjectFactory factory = mocks.CreateMock<IObjectFactory>();
SideEffectObject target = new SideEffectObject();
using (mocks.Record())
{
Expect.Call(factory.IsPrototype("foo")).Return(true);
Expect.Call(factory.GetObject("foo")).Return(target);
Expect.Call(factory.GetType("foo")).Return(typeof(string));
}
using (mocks.Playback())
{
PrototypeTargetSource source = new PrototypeTargetSource();
source.TargetObjectName = "foo";
source.ObjectFactory = factory;
Assert.IsTrue(object.ReferenceEquals(source.GetTarget(), target),
"Initial target source reference not being returned by GetTarget().");
}
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void AfterPropertiesSetWithoutTargetObjectNameBeingSet()
{
PrototypeTargetSource source = new PrototypeTargetSource();
source.AfterPropertiesSet();
}
}
}

View File

@@ -25,7 +25,7 @@ using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using AopAlliance.Intercept;
using DotNetMock.Dynamic;
using Rhino.Mocks;
using NUnit.Framework;
using Spring.Caching;
using Spring.Context;
@@ -43,22 +43,24 @@ namespace Spring.Aspects.Cache
{
object[] IGNORED_ARGS = null;
private IDynamicMock mockInvocation;
private IDynamicMock mockContext;
private IMethodInvocation mockInvocation;
private IApplicationContext mockContext;
private CacheResultAdvice advice;
private ICache resultCache;
private ICache itemCache;
private ICache binaryFormatterCache;
private CacheResultTarget cacheResultTarget = new CacheResultTarget();
private MockRepository mocks;
[SetUp]
public void SetUp()
{
mockInvocation = new DynamicMock( typeof( IMethodInvocation ) );
mockContext = new DynamicMock( typeof( IApplicationContext ) );
mocks = new MockRepository();
mockInvocation = mocks.CreateMock<IMethodInvocation>();
mockContext = mocks.CreateMock<IApplicationContext>();
advice = new CacheResultAdvice();
advice.ApplicationContext = (IApplicationContext)mockContext.Object;
advice.ApplicationContext = mockContext;
resultCache = new NonExpiringCache();
itemCache = new NonExpiringCache();
@@ -72,339 +74,376 @@ namespace Spring.Aspects.Cache
[Test]
public void CacheResultOfMethodThatReturnsNull()
{
MethodInfo method = new VoidMethod( cacheResultTarget.ReturnsNothing ).Method;
MethodInfo method = new VoidMethod(cacheResultTarget.ReturnsNothing).Method;
object expectedReturnValue = null;
ExpectAttributeRetrieval( method );
ExpectCacheKeyGeneration( method, null );
ExpectCacheInstanceRetrieval( "results", resultCache );
ExpectCallToProceed( expectedReturnValue );
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, null);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(expectedReturnValue);
}
using (mocks.Playback())
{
// check that the null retVal is cached as well - it might be
// the result of an expensive webservice/database call etc.
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
}
// check that the null retVal is cached as well - it might be
// the result of an expensive webservice/database call etc.
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, returnValue );
Assert.AreEqual( 1, resultCache.Count );
mockInvocation.Verify();
mockContext.Verify();
}
[Test]
public void CacheResultOfMethodThatReturnsNullWithSerializingCache()
{
MethodInfo method = new VoidMethod(cacheResultTarget.ReturnsNothing).Method;
object expectedReturnValue = null;
MethodInfo method = new VoidMethod(cacheResultTarget.ReturnsNothing).Method;
object expectedReturnValue = null;
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, null);
ExpectCacheInstanceRetrieval("results", binaryFormatterCache);
ExpectCallToProceed(expectedReturnValue);
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, null);
ExpectCacheInstanceRetrieval("results", binaryFormatterCache);
ExpectCallToProceed(expectedReturnValue);
}
// check that the null retVal is cached as well - it might be
// the result of an expensive webservice/database call etc.
object returnValue = advice.Invoke((IMethodInvocation) mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, binaryFormatterCache.Count);
using (mocks.Playback())
{
// check that the null retVal is cached as well - it might be
// the result of an expensive webservice/database call etc.
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, binaryFormatterCache.Count);
// and again, but without Proceed()...
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, null);
ExpectCacheInstanceRetrieval("results", binaryFormatterCache);
// cached value should be returned
object cachedValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.IsNull(cachedValue, "Should recognize cached value as null-value marker.");
mockInvocation.Verify();
mockContext.Verify();
// cached value should be returned
object cachedValue = advice.Invoke(mockInvocation);
Assert.IsNull(cachedValue, "Should recognize cached value as null-value marker.");
}
}
[Test]
public void CacheResultOfMethodThatReturnsObject()
{
MethodInfo method = new IntMethod( cacheResultTarget.ReturnsScalar ).Method;
MethodInfo method = new IntMethod(cacheResultTarget.ReturnsScalar).Method;
object expectedReturnValue = CacheResultTarget.Scalar;
ExpectAttributeRetrieval( method );
ExpectCacheKeyGeneration( method, null );
ExpectCacheInstanceRetrieval( "results", resultCache );
ExpectCallToProceed( expectedReturnValue );
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, null);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(expectedReturnValue);
}
// return value should be added to cache
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, returnValue );
Assert.AreEqual( 1, resultCache.Count );
using (mocks.Playback())
{
// return value should be added to cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
// and again, but without Proceed()...
ExpectAttributeRetrieval( method );
ExpectCacheKeyGeneration( method, null );
ExpectCacheInstanceRetrieval( "results", resultCache );
// cached value should be returned
object cachedValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, cachedValue );
Assert.AreEqual( 1, resultCache.Count );
Assert.AreSame( returnValue, cachedValue );
mockInvocation.Verify();
mockContext.Verify();
// cached value should be returned
object cachedValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, cachedValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreSame(returnValue, cachedValue);
}
}
[Test]
public void CacheResultOfMethodThatReturnsCollection()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.ReturnsCollection ).Method;
object expectedReturnValue = new object[] {"one", "two", "three"};
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.ReturnsCollection).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
}
// return value should be added to cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
using (mocks.Playback())
{
// return value should be added to cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
// and again, but without Proceed()...
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
// cached value should be returned
object cachedValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, cachedValue);
Assert.AreNotSame(expectedReturnValue, cachedValue);
Assert.AreEqual(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual( 1, resultCache.Count );
Assert.AreSame( returnValue, cachedValue );
Assert.AreSame( cachedValue, resultCache.Get( 5 ) );
mockInvocation.Verify();
mockContext.Verify();
// cached value should be returned
object cachedValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, cachedValue);
Assert.AreNotSame(expectedReturnValue, cachedValue);
Assert.AreEqual(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual(1, resultCache.Count);
Assert.AreSame(returnValue, cachedValue);
Assert.AreSame(cachedValue, resultCache.Get(5));
}
}
[Test]
public void CacheResultAndItemsOfMethodThatReturnsCollection()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.ReturnsCollectionAndItems ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.ReturnsCollectionAndItems).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
}
// and again, but without Proceed() and item cache access...
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
using (mocks.Playback())
{
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
// cached value should be returned
object cachedValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, cachedValue);
Assert.AreNotSame(expectedReturnValue, cachedValue);
Assert.AreEqual(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual( 1, resultCache.Count );
Assert.AreEqual( 3, itemCache.Count );
Assert.AreSame( returnValue, cachedValue );
Assert.AreSame( cachedValue, resultCache.Get( 5 ) );
// cached value should be returned
object cachedValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, cachedValue);
Assert.AreNotSame(expectedReturnValue, cachedValue);
Assert.AreEqual(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
Assert.AreSame(returnValue, cachedValue);
Assert.AreSame(cachedValue, resultCache.Get(5));
mockInvocation.Verify();
mockContext.Verify();
}
}
[Test]
public void CacheOnlyItemsOfMethodThatReturnsCollection()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.ReturnsItems ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.ReturnsItems).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
mocks.Record();
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
mocks.ReplayAll();
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
// and again, but without Proceed() and item cache access...
mocks.Verify(mockInvocation);
mocks.BackToRecord(mockInvocation);
ExpectAttributeRetrieval(method);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval( "items", itemCache );
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
// new return value should be returned
object newReturnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, newReturnValue );
Assert.AreEqual( 0, resultCache.Count );
Assert.AreEqual( 3, itemCache.Count );
Assert.AreEqual( "two", itemCache.Get( "two" ) );
Assert.AreNotSame( returnValue, newReturnValue );
mocks.Replay(mockInvocation);
mockInvocation.Verify();
mockContext.Verify();
object newReturnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, newReturnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
Assert.AreEqual("two", itemCache.Get("two"));
Assert.AreNotSame(returnValue, newReturnValue);
mocks.VerifyAll();
}
[Test]
public void CacheOnlyItemsOfMethodThatReturnsCollectionWithinTwoDifferentCaches()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.MultipleCacheResultItems ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.MultipleCacheResultItems).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
mocks.Record();
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval( "items", itemCache );
ExpectCacheInstanceRetrieval( "items", itemCache );
ExpectCacheInstanceRetrieval("items", itemCache);
mocks.ReplayAll();
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, returnValue );
Assert.AreEqual( 0, resultCache.Count );
Assert.AreEqual( 6, itemCache.Count );
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(6, itemCache.Count);
mocks.Verify(mockInvocation);
mocks.BackToRecord(mockInvocation);
// and again, but without Proceed() and item cache access...
ExpectAttributeRetrieval( method );
ExpectCallToProceed( new object[] { "one", "two", "three" } );
ExpectCacheInstanceRetrieval( "items", itemCache );
ExpectCacheInstanceRetrieval( "items", itemCache );
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
mocks.Replay(mockInvocation);
// new return value should be returned
object newReturnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, newReturnValue );
Assert.AreEqual( 0, resultCache.Count );
Assert.AreEqual( 6, itemCache.Count );
Assert.AreEqual( "two", itemCache.Get( "two" ) );
Assert.AreEqual( "two", itemCache.Get( "TWO" ) );
Assert.AreNotSame( returnValue, newReturnValue );
object newReturnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, newReturnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(6, itemCache.Count);
Assert.AreEqual("two", itemCache.Get("two"));
Assert.AreEqual("two", itemCache.Get("TWO"));
Assert.AreNotSame(returnValue, newReturnValue);
mockInvocation.Verify();
mockContext.Verify();
mocks.VerifyAll();
}
[Test]
public void CacheOnlyItemsOfMethodThatReturnsCollectionOnCondition()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.CacheResultItemsWithCondition ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.CacheResultItemsWithCondition).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval( "items", itemCache );
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
}
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, returnValue );
Assert.AreEqual( 2, itemCache.Count );
Assert.AreEqual( "two", itemCache.Get( "two" ) );
Assert.AreEqual( "three", itemCache.Get( "three" ) );
using (mocks.Playback())
{
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(2, itemCache.Count);
Assert.AreEqual("two", itemCache.Get("two"));
Assert.AreEqual("three", itemCache.Get("three"));
}
mockInvocation.Verify();
mockContext.Verify();
}
[Test]
public void CacheResultOfMethodThatReturnsCollectionOnCondition()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.CacheResultWithCondition ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.CacheResultWithCondition).Method;
object expectedReturnValue = new object[] { };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { });
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { });
}
// return value should not be added to cache
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreEqual( expectedReturnValue, returnValue );
Assert.AreEqual( 0, resultCache.Count );
mockInvocation.Verify();
mockContext.Verify();
using (mocks.Playback())
{
// return value should not be added to cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(0, resultCache.Count);
}
}
[Test]
public void AcceptsEnumerableOnlyReturn()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.ReturnsEnumerableOnlyAndItems ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.ReturnsEnumerableOnlyAndItems).Method;
object[] args = new object[] { "one", "two", "three" };
EnumerableOnlyResult expectedReturnValue = new EnumerableOnlyResult(args);
mocks.Record();
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue.InnerArray);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(expectedReturnValue);
ExpectCacheInstanceRetrieval("items", itemCache);
mocks.ReplayAll();
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
Assert.AreSame(expectedReturnValue, returnValue);
Assert.AreSame(expectedReturnValue, resultCache.Get(5));
mocks.Verify(mockInvocation);
mocks.BackToRecord(mockInvocation);
// and again, but without Proceed() and item cache access...
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, IGNORED_ARGS);
ExpectCacheInstanceRetrieval("results", resultCache);
mocks.Replay(mockInvocation);
// cached value should be returned, cache remains unchanged
object cachedValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
object cachedValue = advice.Invoke(mockInvocation);
Assert.AreSame(expectedReturnValue, cachedValue);
Assert.AreSame(returnValue, cachedValue );
Assert.AreSame(returnValue, cachedValue);
Assert.AreSame(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual( 1, resultCache.Count );
Assert.AreEqual( 3, itemCache.Count );
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
mockInvocation.Verify();
mockContext.Verify();
mocks.VerifyAll();
}
[Test]
public void CacheResultOfMethodThatReturnsCollectionContainingNullItems()
{
MethodInfo method = new EnumerableResultMethod( cacheResultTarget.ReturnsEnumerableOnlyAndItems ).Method;
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.ReturnsEnumerableOnlyAndItems).Method;
object expectedReturnValue = new object[] { null, "two", null };
ExpectAttributeRetrieval( method );
ExpectCacheKeyGeneration( method, 5, expectedReturnValue );
ExpectCacheInstanceRetrieval( "results", resultCache );
ExpectCallToProceed( expectedReturnValue );
ExpectCacheInstanceRetrieval( "items", itemCache );
mocks.Record();
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(expectedReturnValue);
ExpectCacheInstanceRetrieval("items", itemCache);
mocks.ReplayAll();
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
Assert.AreSame( expectedReturnValue, returnValue );
Assert.AreEqual( 1, resultCache.Count );
Assert.AreEqual( 2, itemCache.Count ); // 2 null items result into 1 cached item
object returnValue = advice.Invoke(mockInvocation);
Assert.AreSame(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(2, itemCache.Count); // 2 null items result into 1 cached item
mocks.Verify(mockInvocation);
mocks.BackToRecord(mockInvocation);
// and again, but without Proceed() and item cache access...
ExpectAttributeRetrieval( method );
ExpectCacheKeyGeneration( method, 5, IGNORED_ARGS );
ExpectCacheInstanceRetrieval( "results", resultCache );
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, IGNORED_ARGS);
mocks.Replay(mockInvocation);
// cached value should be returned
object cachedValue = advice.Invoke( (IMethodInvocation)mockInvocation.Object );
object cachedValue = advice.Invoke(mockInvocation);
Assert.AreSame(expectedReturnValue, cachedValue);
Assert.AreSame(returnValue, cachedValue );
Assert.AreSame(returnValue, cachedValue);
Assert.AreSame(expectedReturnValue, resultCache.Get(5));
Assert.AreEqual( 1, resultCache.Count );
Assert.AreEqual( 2, itemCache.Count );
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(2, itemCache.Count);
mockInvocation.Verify();
mockContext.Verify();
mocks.VerifyAll();
}
[Test]
@@ -413,19 +452,22 @@ namespace Spring.Aspects.Cache
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.CacheResultWithMethodInfo).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCacheInstanceRetrieval("results", resultCache);
ExpectCallToProceed(new object[] { "one", "two", "three" });
}
// return value should be added to cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(returnValue, resultCache.Get("CacheResultWithMethodInfo-5"));
mockInvocation.Verify();
mockContext.Verify();
using (mocks.Playback())
{
// return value should be added to cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(1, resultCache.Count);
Assert.AreEqual(returnValue, resultCache.Get("CacheResultWithMethodInfo-5"));
}
}
[Test]
@@ -434,44 +476,57 @@ namespace Spring.Aspects.Cache
MethodInfo method = new EnumerableResultMethod(cacheResultTarget.CacheResultItemsWithMethodInfo).Method;
object expectedReturnValue = new object[] { "one", "two", "three" };
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
using (mocks.Record())
{
ExpectAttributeRetrieval(method);
ExpectCacheKeyGeneration(method, 5, expectedReturnValue);
ExpectCallToProceed(new object[] { "one", "two", "three" });
ExpectCacheInstanceRetrieval("items", itemCache);
}
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke((IMethodInvocation)mockInvocation.Object);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
Assert.AreEqual("two", itemCache.Get("CacheResultItemsWithMethodInfo-two"));
using (mocks.Playback())
{
// return value should be added to result cache and each item to item cache
object returnValue = advice.Invoke(mockInvocation);
Assert.AreEqual(expectedReturnValue, returnValue);
Assert.AreEqual(0, resultCache.Count);
Assert.AreEqual(3, itemCache.Count);
Assert.AreEqual("two", itemCache.Get("CacheResultItemsWithMethodInfo-two"));
}
mockInvocation.Verify();
mockContext.Verify();
}
#region Helper methods
private void ExpectAttributeRetrieval( MethodInfo method )
private void ExpectAttributeRetrieval(MethodInfo method)
{
mockInvocation.SetValue( "Method", method );
Expect.Call(mockInvocation.Method).Return(method).Repeat.AtLeastOnce();
}
private void ExpectCacheKeyGeneration( MethodInfo method, params object[] arguments )
private void ExpectCacheKeyGeneration(MethodInfo method, params object[] arguments)
{
// mockInvocation.ExpectAndReturn( "Method", method );
mockInvocation.SetValue( "Arguments", arguments );
Expect.Call(mockInvocation.Arguments).Return(arguments).Repeat.AtLeastOnce();
}
private void ExpectCacheInstanceRetrieval( string cacheName, ICache cache )
private void ExpectCacheInstanceRetrieval(string cacheName, ICache cache)
{
mockContext.ExpectAndReturn( "GetObject", cache, cacheName );
Expect.Call(mockContext.GetObject(cacheName)).Return(cache).Repeat.AtLeastOnce();
}
private void ExpectCallToProceed( object expectedReturnValue )
private void ExpectCacheInstanceRetrieval(string cacheName, ICache cache, int repeatTimes)
{
mockInvocation.ExpectAndReturn( "Proceed", expectedReturnValue );
Expect.Call(mockContext.GetObject(cacheName)).Return(cache).Repeat.Times(repeatTimes);
}
private void ExpectCallToProceed(object expectedReturnValue, int repeatTimes)
{
Expect.Call(mockInvocation.Proceed()).Return(expectedReturnValue).Repeat.Times(repeatTimes);
}
private void ExpectCallToProceed(object expectedReturnValue)
{
Expect.Call(mockInvocation.Proceed()).Return(expectedReturnValue);
}
#endregion
@@ -482,13 +537,13 @@ namespace Spring.Aspects.Cache
public delegate void VoidMethod();
public delegate int IntMethod();
public delegate IEnumerable EnumerableResultMethod( int key, params object[] elements );
public delegate IEnumerable EnumerableResultMethod(int key, params object[] elements);
public class EnumerableOnlyResult : IEnumerable
{
private object[] _args;
public EnumerableOnlyResult( params object[] args )
public EnumerableOnlyResult(params object[] args)
{
_args = args;
}
@@ -498,9 +553,9 @@ namespace Spring.Aspects.Cache
return _args.GetEnumerator();
}
public override bool Equals( object obj )
public override bool Equals(object obj)
{
Assert.AreEqual(_args, ((EnumerableOnlyResult)obj)._args );
Assert.AreEqual(_args, ((EnumerableOnlyResult)obj)._args);
return true;
}
@@ -526,55 +581,55 @@ namespace Spring.Aspects.Cache
{
void ReturnsNothing();
int ReturnsScalar();
IEnumerable ReturnsCollection( int key, params object[] elements );
IEnumerable ReturnsCollectionAndItems( int key, params object[] elements );
IEnumerable ReturnsItems( int key, params object[] elements );
IEnumerable ReturnsCollection(int key, params object[] elements);
IEnumerable ReturnsCollectionAndItems(int key, params object[] elements);
IEnumerable ReturnsItems(int key, params object[] elements);
}
public sealed class CacheResultTarget : ICacheResultTarget
{
public const int Scalar = int.MaxValue;
[CacheResult( "results", "'key'" )]
[CacheResult("results", "'key'")]
public void ReturnsNothing()
{
}
[CacheResult( "results", "'key'" )]
[CacheResult("results", "'key'")]
public int ReturnsScalar()
{
return Scalar;
}
[CacheResult( "results", "#key" )]
public IEnumerable ReturnsCollection( int key, params object[] elements )
[CacheResult("results", "#key")]
public IEnumerable ReturnsCollection(int key, params object[] elements)
{
return elements;
}
[CacheResult( "results", "#key" )]
[CacheResultItems( "items", "''+#this" )]
public IEnumerable ReturnsCollectionAndItems( int key, params object[] elements )
[CacheResult("results", "#key")]
[CacheResultItems("items", "''+#this")]
public IEnumerable ReturnsCollectionAndItems(int key, params object[] elements)
{
return elements;
}
[CacheResult( "results", "#key" )]
[CacheResultItems( "items", "''+#this" )]
public IEnumerable ReturnsEnumerableOnlyAndItems( int key, params object[] elements )
[CacheResult("results", "#key")]
[CacheResultItems("items", "''+#this")]
public IEnumerable ReturnsEnumerableOnlyAndItems(int key, params object[] elements)
{
return new EnumerableOnlyResult(elements);
}
[CacheResultItems( "items", "#this" )]
public IEnumerable ReturnsItems( int key, params object[] elements )
[CacheResultItems("items", "#this")]
public IEnumerable ReturnsItems(int key, params object[] elements)
{
return elements;
}
[CacheResultItems( "items", "#this" )]
[CacheResultItems( "items", "#this.ToUpper()" )]
public IEnumerable MultipleCacheResultItems( int key, params object[] elements )
[CacheResultItems("items", "#this")]
[CacheResultItems("items", "#this.ToUpper()")]
public IEnumerable MultipleCacheResultItems(int key, params object[] elements)
{
return elements;
}
@@ -591,14 +646,14 @@ namespace Spring.Aspects.Cache
return elements;
}
[CacheResultItems( "items", "#this", Condition = "#this.StartsWith('t')" )]
public IEnumerable CacheResultItemsWithCondition( int key, params object[] elements )
[CacheResultItems("items", "#this", Condition = "#this.StartsWith('t')")]
public IEnumerable CacheResultItemsWithCondition(int key, params object[] elements)
{
return elements;
}
[CacheResult( "results", "#key", Condition = "#this.Length > 0" )]
public IEnumerable CacheResultWithCondition( int key, params object[] elements )
[CacheResult("results", "#key", Condition = "#this.Length > 0")]
public IEnumerable CacheResultWithCondition(int key, params object[] elements)
{
return elements;
}
@@ -623,7 +678,7 @@ namespace Spring.Aspects.Cache
public override object Get(object key)
{
byte[] bytes = (byte[]) base.Get(key);
byte[] bytes = (byte[])base.Get(key);
if (bytes == null)
{

View File

@@ -22,7 +22,7 @@
using System;
using System.Reflection;
using DotNetMock.Dynamic;
using Rhino.Mocks;
using NUnit.Framework;
using Spring.Context;
using Spring.Validation;
@@ -39,17 +39,19 @@ namespace Spring.Aspects.Validation
[TestFixture]
public sealed class ParameterValidationAdviceTests
{
private IDynamicMock mockContext;
private IApplicationContext mockContext;
private ParameterValidationAdvice advice;
private RequiredValidator requiredValidator;
private MockRepository mocks;
[SetUp]
public void SetUp()
{
mockContext = new DynamicMock(typeof (IApplicationContext));
mocks = new MockRepository();
mockContext = mocks.CreateMock<IApplicationContext>();
advice = new ParameterValidationAdvice();
advice.ApplicationContext = (IApplicationContext) mockContext.Object;
advice.ApplicationContext = mockContext;
requiredValidator = new RequiredValidator();
requiredValidator.Actions.Add(new ErrorMessageAction("error.required", "errors"));
@@ -63,13 +65,18 @@ namespace Spring.Aspects.Validation
ValidationTarget target = new ValidationTarget();
object[] args = new object[] {inventor};
ExpectValidatorRetrieval("required", requiredValidator);
advice.Before(method, args, target);
method.Invoke(target, args);
using (mocks.Record())
{
ExpectValidatorRetrieval("required", requiredValidator);
}
Assert.AreEqual("NIKOLA TESLA", inventor.Name);
using (mocks.Playback())
{
advice.Before(method, args, target);
method.Invoke(target, args);
Assert.AreEqual("NIKOLA TESLA", inventor.Name);
}
mockContext.Verify();
}
[Test]
@@ -78,16 +85,22 @@ namespace Spring.Aspects.Validation
{
MethodInfo method = typeof(ValidationTarget).GetMethod("Save");
ExpectValidatorRetrieval("required", requiredValidator);
advice.Before(method, new object[] { null }, new ValidationTarget());
mockContext.Verify();
using (mocks.Record())
{
ExpectValidatorRetrieval("required", requiredValidator);
}
using (mocks.Playback())
{
advice.Before(method, new object[] { null }, new ValidationTarget());
}
}
#region Helper methods
private void ExpectValidatorRetrieval(string validatorName, IValidator validator)
{
mockContext.ExpectAndReturn("GetObject", validator, validatorName);
Expect.Call(mockContext.GetObject(validatorName)).Return(validator);
}
#endregion

View File

@@ -123,13 +123,23 @@ namespace Spring.Context.Support
return null;
}
public string[] GetObjectNamesForType(
public string[] GetObjectNamesForType<T>()
{
return null;
}
public string[] GetObjectNamesForType(
Type type, bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
string[] IListableObjectFactory.GetObjectDefinitionNames()
public string[] GetObjectNamesForType<T>(bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
string[] IListableObjectFactory.GetObjectDefinitionNames()
{
return null;
}
@@ -139,12 +149,27 @@ namespace Spring.Context.Support
return null;
}
public IDictionary GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IDictionary GetObjectsOfType<T>()
{
return null;
}
public IDictionary GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
public int ObjectDefinitionCount
public IDictionary GetObjectsOfType<T>(bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
public T GetObject<T>()
{
throw new NotImplementedException();
}
public int ObjectDefinitionCount
{
get { return 0; }
}
@@ -178,12 +203,22 @@ namespace Spring.Context.Support
return null;
}
public bool IsTypeMatch<T>(string name)
{
return false;
}
public object CreateObject(string name, Type requiredType, object[] arguments)
{
return null;
}
public object GetObject(string name, Type requiredType)
public T CreateObject<T>(string name, object[] arguments)
{
return Activator.CreateInstance<T>();
}
public object GetObject(string name, Type requiredType)
{
return null;
}
@@ -193,11 +228,21 @@ namespace Spring.Context.Support
return null;
}
public T GetObject<T>(string name)
{
return Activator.CreateInstance<T>();
}
public object GetObject(string name, object[] arguments)
{
return null;
}
public T GetObject<T>(string name, object[] arguments)
{
return Activator.CreateInstance<T>();
}
public object GetObject(string name, Type requiredType, object[] arguments)
{
return null;