#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
#region Imports
using System;
using NUnit.Framework;
using Spring.Expressions;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
#endregion
namespace Spring.Objects.Factory{
/// <summary>
/// Subclasses must override SetUp () to initialize the object factory
/// and any other variables they need.
/// </summary>
/// <author>Rod Johnson</author>
/// <author>Rick Evans (.NET)</author>
public abstract class AbstractObjectFactoryTests
{
#region Properties
protected internal abstract AbstractObjectFactory CreateObjectFactory(bool caseSensitive);
private AbstractObjectFactory cachedFactory;
protected AbstractObjectFactory ObjectFactory
{
get { return cachedFactory; }
set { cachedFactory = value; }
}
#endregion
#region Case Insensitive Tests
[Test]
public void RespectsCaseInsensitiveNamesAndAliases()
{
AbstractObjectFactory of = CreateObjectFactory(false);
object testObject = new object();
of.RegisterSingleton("name", testObject);
of.RegisterAlias("NAME", "alias");
try
{
of.RegisterAlias("NaMe", "AlIaS");
Assert.Fail();
}
catch (ObjectDefinitionStoreException ex)
{
Assert.IsTrue( -1<ex.Message.IndexOf("already registered") );
}
Assert.AreEqual(1, of.GetAliases("nAmE").Length);
Assert.AreEqual(testObject, of.GetObject("nAmE"));
Assert.AreEqual(testObject, of.GetObject("ALIAS"));
}
#endregion
/// <summary>
/// Roderick objects inherits from rod, overriding name only.
/// </summary>
[Test]
public void Inheritance()
{
Assert.IsTrue(ObjectFactory.ContainsObject("rod"));
Assert.IsTrue(ObjectFactory.ContainsObject("roderick"));
TestObject rod = (TestObject) ObjectFactory["rod"];
TestObject roderick = (TestObject) ObjectFactory["roderick"];
Assert.IsTrue(rod != roderick, "not == ");
Assert.IsTrue(rod.Name.Equals("Rod"), "rod.name is Rod");
Assert.IsTrue(rod.Age == 31, "rod.age is 31");
Assert.IsTrue(roderick.Name.Equals("Roderick"), "roderick.name is Roderick");
Assert.IsTrue(roderick.Age == rod.Age, "roderick.age was inherited");
}
[Test]
[ExpectedException(typeof (ArgumentNullException))]
public virtual void GetObjectWithNullName()
{
ObjectFactory.GetObject(null);
}
/// <summary>
/// Test that InitializingObject objects receive the AfterPropertiesSet () callback.
/// </summary>
[Test]
public void InitializingObjectCallback()
{
MustBeInitialized mbi =
(MustBeInitialized) ObjectFactory["mustBeInitialized"];
// The dummy business method will throw an exception if the
// AfterPropertiesSet () callback wasn't invoked
mbi.BusinessMethod();
}
/// <summary>
/// Test that InitializingObject/ObjectFactoryAware/DisposableObject objects
/// receive the AfterPropertiesSet () callback before ObjectFactoryAware
/// callbacks.
/// </summary>
[Test]
public void LifecycleCallbacks()
{
LifecycleObject lb = (LifecycleObject) ObjectFactory.GetObject("lifecycle");
Assert.AreEqual("lifecycle", lb.ObjectName);
// The dummy business method will throw an exception if the
// necessary callbacks weren't invoked in the right order
lb.BusinessMethod();
Assert.IsFalse(lb.Destroyed, "Was destroyed");
}
[Test(Description = "SPRNET-1208")]
public void AddObjectFactoryOnObjectFactoryAwareObjectPostProcessors()
{
AbstractObjectFactory aof = ObjectFactory;
LifecycleObject.PostProcessor lb = new LifecycleObject.PostProcessor();
aof.AddObjectPostProcessor(lb);
Assert.AreSame( aof, lb.ObjectFactory );
}
[Test]
public void FindsValidInstance()
{
object o = ObjectFactory.GetObject("rod");
Assert.IsTrue(o is TestObject, "Rod object is a TestObject");
TestObject rod = (TestObject) o;
Assert.IsTrue(rod.Name.Equals("Rod"), "rod.name is Rod");
Assert.IsTrue(rod.Age == 31, "rod.age is 31");
}
[Test]
public void GetInstanceByMatchingClass()
{
object o = ObjectFactory.GetObject("rod", typeof (TestObject));
Assert.IsTrue(o is TestObject, "Rod object is a TestObject");
}
[Test]
public void GetInstanceByNonmatchingClass()
{
try
{
ObjectFactory.GetObject("rod", typeof (IObjectFactory));
Assert.Fail("Rod object is not of type IObjectFactory; GetObjectInstance(rod, typeof (IObjectFactory)) should throw ObjectNotOfRequiredTypeException");
}
catch (ObjectNotOfRequiredTypeException ex)
{
Assert.IsTrue(ex.ObjectName.Equals("rod"), "Exception has correct object name");
Assert.IsTrue(ex.RequiredType.Equals(typeof (IObjectFactory)), "Exception requiredType must be ObjectFactory.class");
Assert.IsTrue(typeof (TestObject).IsAssignableFrom(ex.ActualType), "Exception actualType as TestObject.class");
Assert.IsTrue(ex.ActualInstance == ObjectFactory.GetObject("rod"), "Actual instance is correct");
}
}
[Test]
public virtual void GetSharedInstanceByMatchingClass()
{
object o = ObjectFactory.GetObject("rod", typeof (TestObject));
Assert.IsTrue(o is TestObject, "Rod object is a TestObject");
}
[Test]
public virtual void GetSharedInstanceByMatchingClassNoCatch()
{
object o = ObjectFactory.GetObject("rod", typeof (TestObject));
Assert.IsTrue(o is TestObject, "Rod object is a TestObject");
}
[Test]
public void GetSharedInstanceByNonmatchingClass()
{
try
{
ObjectFactory.GetObject("rod", typeof (IObjectFactory));
Assert.Fail("Rod object is not of type ObjectFactory; getObjectInstance(rod, ObjectFactory.class) should throw ObjectNotOfRequiredTypeException");
}
catch (ObjectNotOfRequiredTypeException ex)
{
// So far, so good
Assert.IsTrue(ex.ObjectName.Equals("rod"), "Exception has correct object name");
Assert.IsTrue(ex.RequiredType.Equals(typeof (IObjectFactory)), "Exception requiredType must be IObjectFactory class");
Assert.IsTrue(typeof (TestObject).IsAssignableFrom(ex.ActualType), "Exception actualType as TestObject class");
}
catch (Exception ex)
{
Assert.Fail("Shouldn't throw exception on getting valid instance with matching class : " + ex.Message);
}
}
[Test]
public virtual void SharedInstancesAreEqual()
{
try
{
object o = ObjectFactory.GetObject("rod");
Assert.IsTrue(o is TestObject, "Rod object1 is a TestObject");
object o1 = ObjectFactory.GetObject("rod");
Assert.IsTrue(o1 is TestObject, "Rod object2 is a TestObject");
Assert.IsTrue(o == o1, "Object equals applies");
}
catch
{
Assert.Fail("Shouldn't throw exception on getting valid instance");
}
}
[Test]
[ExpectedException(typeof (NoSuchObjectDefinitionException))]
public void NotThere()
{
Assert.IsFalse(ObjectFactory.ContainsObject("Mr Squiggle"));
ObjectFactory.GetObject("Mr Squiggle");
}
[Test]
public void ValidEmpty()
{
try
{
object o = ObjectFactory.GetObject("validEmpty");
Assert.IsTrue(o is TestObject, "validEmpty object is a TestObject");
TestObject ve = (TestObject) o;
Assert.IsTrue(ve.Name == null && ve.Age == 0 && ve.Spouse == null, "Valid empty has defaults");
}
catch
{
Assert.Fail("Shouldn't throw exception on valid empty");
}
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void RegisterNullCustomTypeConverter()
{
ObjectFactory.RegisterCustomConverter(null, null);
}
[Test]
public virtual void TypeMismatch()
{
try
{
ObjectFactory.GetObject("typeMismatch");
Assert.Fail("Shouldn't succeed with type mismatch");
}
catch (ObjectCreationException wex)
{
Assert.IsTrue(wex.InnerException is PropertyAccessExceptionsException);
PropertyAccessExceptionsException ex = (PropertyAccessExceptionsException) wex.InnerException;
// Furthers
Assert.IsTrue(ex.ExceptionCount == 1, "Has one error");
Assert.IsTrue(ex.GetPropertyAccessException("age") != null, "Error is for field age");
TestObject tb = (TestObject) ex.ObjectWrapper.WrappedInstance;
Assert.IsTrue(tb.Age == 0, "Age still has default");
Assert.IsTrue(ex.GetPropertyAccessException("age").PropertyChangeArgs.NewValue.Equals("34x"), "We have rejected age in exception");
Assert.IsTrue(tb.Name.Equals("typeMismatch"), "valid name stuck");
Assert.IsTrue(tb.Spouse.Name.Equals("Rod"), "valid spouse stuck");
}
}
[Test]
public virtual void GrandParentDefinitionFoundInObjectFactory()
{
TestObject dad = (TestObject) ObjectFactory.GetObject("father");
Assert.IsTrue(dad.Name.Equals("Albert"), "Dad has correct name");
}
[Test]
public virtual void GrandParentDefinitionFoundInObjectFactoryWithType()
{
TestObject dad = (TestObject)ObjectFactory.GetObject("typedfather", typeof(TestObject));
Assert.AreEqual(null, dad.Name, "Dad has not correct name");
}
[Test]
public virtual void GrandParentDefinitionFoundInObjectFactoryWithArguments()
{
TestObject dad = (TestObject)ObjectFactory.GetObject("namedfather", new object[] { "Hugo", 65 } );
Assert.AreEqual("Hugo", dad.Name, "Dad has not correct name");
Assert.AreEqual(65, dad.Age, "Dad has not correct age");
}
[Test]
public virtual void GrandParentDefinitionFoundInObjectFactoryWithTypeAndArguments()
{
TestObject dad = (TestObject)ObjectFactory.GetObject("typedfather", typeof(TestObject), new object[] { "Chris", 66 });
Assert.AreEqual("Chris", dad.Name, "Dad has not correct name");
Assert.AreEqual(66, dad.Age, "Dad has not correct age");
}
[Test(Description="Extra check that the type is really passed on to the parent factory")]
public virtual void GrandParentDefinitionFoundInObjectFactoryWithTypeAndArgumentsWithWrongType()
{
try
{
TestObject dad = (TestObject)ObjectFactory.GetObject("typedfather", typeof(string), new object[] { "Chris", 66 });
Assert.Fail("should throw ObjectNotOfRequiredTypeException");
}
catch (ObjectNotOfRequiredTypeException)
{
}
}
[Test]
public virtual void FactorySingleton()
{
Assert.IsTrue(ObjectFactory.IsSingleton("&singletonFactory"));
Assert.IsTrue(ObjectFactory.IsSingleton("singletonFactory"));
TestObject tb = (TestObject) ObjectFactory.GetObject("singletonFactory");
Assert.IsTrue(tb.Name.Equals(DummyFactory.SINGLETON_NAME), "Singleton from factory has correct name, not " + tb.Name);
DummyFactory factory = (DummyFactory) ObjectFactory.GetObject("&singletonFactory");
TestObject tb2 = (TestObject) ObjectFactory.GetObject("singletonFactory");
Assert.IsTrue(tb == tb2, "Singleton references ==");
Assert.IsTrue(factory.ObjectFactory != null, "FactoryObject is ObjectFactoryAware");
}
[Test]
public virtual void FactoryPrototype()
{
Assert.IsTrue(ObjectFactory.IsSingleton("&prototypeFactory"));
Assert.IsFalse(ObjectFactory.IsSingleton("prototypeFactory"));
TestObject tb = (TestObject) ObjectFactory.GetObject("prototypeFactory");
Assert.IsTrue(!tb.Name.Equals(DummyFactory.SINGLETON_NAME));
TestObject tb2 = (TestObject) ObjectFactory.GetObject("prototypeFactory");
Assert.IsTrue(tb != tb2, "Prototype references !=");
}
/// <summary>
/// Check that we can get the factory object itself.
/// This is only possible if we're dealing with a factory
/// </summary>
[Test]
public virtual void GetFactoryItself()
{
DummyFactory factory = (DummyFactory) ObjectFactory.GetObject("&singletonFactory");
Assert.IsTrue(factory != null);
}
/// <summary>Check that AfterPropertiesSet gets called on factory.</summary>
[Test]
public virtual void FactoryIsInitialized()
{
TestObject tb = (TestObject) ObjectFactory.GetObject("singletonFactory");
DummyFactory factory = (DummyFactory) ObjectFactory.GetObject("&singletonFactory");
Assert.IsTrue(factory.WasInitialized, "Factory was not initialized even though it implemented IInitializingObject");
}
/// <summary>
/// It should be illegal to dereference a normal object as a factory.
/// </summary>
[Test]
[ExpectedException(typeof (ObjectIsNotAFactoryException))]
public virtual void RejectsFactoryGetOnNormalObject()
{
ObjectFactory.GetObject("&rod");
}
[Test]
[ExpectedException(typeof (ObjectDefinitionStoreException))]
public virtual void Aliasing()
{
string alias = "rods alias";
try
{
ObjectFactory.GetObject(alias);
Assert.Fail("Shouldn't permit factory get on normal object");
}
catch (NoSuchObjectDefinitionException ex)
{
Assert.IsTrue(alias.Equals(ex.ObjectName));
}
// Create alias
ObjectFactory.RegisterAlias("rod", alias);
object rod = ObjectFactory.GetObject("rod");
object aliasRod = ObjectFactory.GetObject(alias);
Assert.IsTrue(rod == aliasRod);
ObjectFactory.RegisterAlias("father", alias);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void RegisterSingletonWithEmptyName()
{
((AbstractObjectFactory) ObjectFactory)
.RegisterSingleton(Environment.NewLine, DBNull.Value);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void RegisterSingletonWithNullName()
{
((AbstractObjectFactory) ObjectFactory)
.RegisterSingleton(null, DBNull.Value);
}
#if NET_2_0
[Test]
public void GetSingletonNamesReflectsOrderOfRegistration()
{
AbstractObjectFactory of;
of = CreateObjectFactory(true);
of.RegisterSingleton("A", new object());
of.RegisterSingleton("C", new object());
of.RegisterSingleton("B", new object());
Assert.AreEqual(new string[] { "A", "C", "B"}, of.GetSingletonNames());
of = CreateObjectFactory(false);
of.RegisterSingleton("A", new object());
of.RegisterSingleton("C", new object());
of.RegisterSingleton("B", new object());
Assert.AreEqual(new string[] { "A", "C", "B"}, of.GetSingletonNames(typeof(object)));
}
#endif
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ContainsSingletonWithEmptyName()
{
((AbstractObjectFactory) ObjectFactory)
.ContainsSingleton(Environment.NewLine);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ContainsSingletonWithNullName()
{
((AbstractObjectFactory) ObjectFactory)
.ContainsSingleton(null);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void AliasWithEmptyName()
{
((AbstractObjectFactory) ObjectFactory).RegisterAlias(Environment.NewLine, "the whipping boy");
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void AliasWithEmptyAlias()
{
((AbstractObjectFactory) ObjectFactory).RegisterAlias("rick", Environment.NewLine);
}
// [Test]
// [ExpectedException(typeof(ObjectDefinitionStoreException))]
// public void ChokesIfNotGivenSupportedIObjectDefinitionImplementation()
// {
// ObjectFactory.GetObject("unsupportedDefinition");
// }
/// <summary>
/// This test resembles a scenario that may happen e.g. using ProxyFactoryObject proxying sibling objects with cyclic dependencies
/// </summary>
[Test]
public void CanResolveCyclicSingletonFactoryObjectProductDependencies()
{
AbstractObjectFactory of = this.CreateObjectFactory(true);
GenericObjectDefinition od = new GenericObjectDefinition();
od.ObjectTypeName = typeof(TestObject).FullName;
od.IsSingleton = true;
od.PropertyValues.Add(new PropertyValue("Spouse", new RuntimeObjectReference("product2")));
of.RegisterObjectDefinition("product1Target", od);
GenericObjectDefinition od2 = new GenericObjectDefinition();
od2.ObjectTypeName = typeof(TestObject).FullName;
od2.IsSingleton = true;
od2.PropertyValues.Add(new PropertyValue("Sibling", new RuntimeObjectReference("product1")));
of.RegisterObjectDefinition("product2Target", od2);
of.RegisterSingleton("product1", new ObjectReferenceFactoryObject("product1Target", of));
of.RegisterSingleton("product2", new ObjectReferenceFactoryObject("product2Target", of));
TestObject to = (TestObject) of.GetObject("product1");
Assert.NotNull(to);
Assert.NotNull(to.Spouse);
Assert.NotNull( ((TestObject)to.Spouse).Sibling);
}
[Test]
public void ThrowsOnCyclicDependenciesOnNonSingletons()
{
AbstractObjectFactory of = this.CreateObjectFactory(true);
GenericObjectDefinition od = new GenericObjectDefinition();
od.ObjectTypeName = typeof(TestObject).FullName;
od.IsSingleton = false;
od.PropertyValues.Add(new PropertyValue("Spouse", new RuntimeObjectReference("product2")));
of.RegisterObjectDefinition("product1", od);
GenericObjectDefinition od2 = new GenericObjectDefinition();
od2.ObjectTypeName = typeof(TestObject).FullName;
od2.IsSingleton = false;
od2.PropertyValues.Add(new PropertyValue("Sibling", new RuntimeObjectReference("product1")));
of.RegisterObjectDefinition("product2", od2);
try
{
of.GetObject("product1");
Assert.Fail();
}
catch (ObjectCurrentlyInCreationException ex)
{
Assert.AreEqual("product1", ex.ObjectName);
}
}
}
}
|