/* * Copyright 2008, Unitils.org * * 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. */ package org.unitils.inject; import static org.junit.Assert.assertSame; import org.junit.Before; import org.junit.Test; import org.unitils.core.ConfigurationLoader; import org.unitils.inject.annotation.InjectIntoByType; import org.unitils.inject.annotation.TestedObject; import org.unitils.inject.util.PropertyAccess; import java.util.Properties; /** * Test for the auto injection behavior of the {@link InjectModule} * * @author Filip Neven * @author Tim Ducheyne */ public class InjectModuleInjectIntoByTypeTest { /* Tested object */ private InjectModule injectModule; /* Objects that represent 'unit test classes', containing objects that should be injected on other objects. */ private TestInjectIntoByTypeExplicitTarget testInjectIntoByTypeExplicitTarget = new TestInjectIntoByTypeExplicitTarget(); private TestInjectIntoByTypeFieldAccess testInjectIntoByTypeFieldAccess = new TestInjectIntoByTypeFieldAccess(); private TestInjectIntoByTypeAnnotatedTarget testInjectIntoByTypeAnnotatedTarget = new TestInjectIntoByTypeAnnotatedTarget(); private TestInjectIntoByType_targetPropertyIsSuperType testInjectIntoByType_targetPropertyIsSuperType = new TestInjectIntoByType_targetPropertyIsSuperType(); private TestInjectIntoByType_targetPropertyIsSuperType_fieldAccess testInjectIntoByType_targetPropertyIsSuperType_fieldAccess = new TestInjectIntoByType_targetPropertyIsSuperType_fieldAccess(); private TestInjectIntoByTypeToMostSpecificallyTypedProperty testInjectIntoByTypeToMostSpecificallyTypedProperty = new TestInjectIntoByTypeToMostSpecificallyTypedProperty(); private TestInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess = new TestInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess(); private TestInjectIntoByType_targetPropertyOnSuperClass testInjectIntoByType_targetPropertyOnSuperClass = new TestInjectIntoByType_targetPropertyOnSuperClass(); private TestInjectIntoByType_targetPropertyOnSuperClass_fieldAccess testInjectIntoByType_targetPropertyOnSuperClass_fieldAccess = new TestInjectIntoByType_targetPropertyOnSuperClass_fieldAccess(); /** * Initializes the test and test fixture. */ @Before public void setUp() throws Exception { Properties configuration = new ConfigurationLoader().loadConfiguration(); injectModule = new InjectModule(); injectModule.init(configuration); } /** * Tests auto injection in case the target is explicitly specified */ @Test public void testInjectIntoByType_explicitTarget() { injectModule.injectObjects(testInjectIntoByTypeExplicitTarget); assertSame(testInjectIntoByTypeExplicitTarget.getToInject(), testInjectIntoByTypeExplicitTarget.getInjectOn().getToInject()); } /** * Tests auto injection in case of field access */ @Test public void testInjectIntoByType_fieldAccess() { injectModule.injectObjects(testInjectIntoByTypeFieldAccess); assertSame(testInjectIntoByTypeFieldAccess.getToInject(), testInjectIntoByTypeFieldAccess.getInjectOnField().getToInject()); } /** * Multiple fields are annotated with @TestedObject. Tests wether the objects are injected to all of these fields */ @Test public void testInjectIntoByType_annotatedTargets() { injectModule.injectObjects(testInjectIntoByTypeAnnotatedTarget); assertSame(testInjectIntoByTypeAnnotatedTarget.getToInject(), testInjectIntoByTypeAnnotatedTarget.getInjectOn1().getToInject()); assertSame(testInjectIntoByTypeAnnotatedTarget.getToInject(), testInjectIntoByTypeAnnotatedTarget.getInjectOn2().getToInject()); } /** * Tests the case when the target field is a supertype of the injected object, and no more specific field exists. */ @Test public void testInjectIntoByType_targetFieldIsSuperType() { injectModule.injectObjects(testInjectIntoByType_targetPropertyIsSuperType); assertSame(testInjectIntoByType_targetPropertyIsSuperType.getToInject(), testInjectIntoByType_targetPropertyIsSuperType.getInjectOn().getToInject()); } /** * Tests the case when the target field is a supertype of the injected object, and no more specific field exists, * using field access */ @Test public void testInjectIntoByType_targetFieldIsSuperType_fieldAccess() { injectModule.injectObjects(testInjectIntoByType_targetPropertyIsSuperType_fieldAccess); assertSame(testInjectIntoByType_targetPropertyIsSuperType_fieldAccess.getToInject(), testInjectIntoByType_targetPropertyIsSuperType_fieldAccess.getInjectOn().getToInject()); } /** * Tests the case where target fields of both the object's type and a super type exists. The object should be injected * into the most specific type */ @Test public void testInjectIntoByType_injectToMostSpecificallyTypedField() { injectModule.injectObjects(testInjectIntoByTypeToMostSpecificallyTypedProperty); assertSame(testInjectIntoByTypeToMostSpecificallyTypedProperty.getToInjectSuper(), testInjectIntoByTypeToMostSpecificallyTypedProperty.getInjectOn().getToInjectSuper()); assertSame(testInjectIntoByTypeToMostSpecificallyTypedProperty.getToInjectSub(), testInjectIntoByTypeToMostSpecificallyTypedProperty.getInjectOn().getToInjectSub()); } /** * Tests the case where target fields of both the object's type and a super type exists. The object should be injected * into the most specific type. Field access is used. */ @Test public void testInjectIntoByType_injectToMostSpecificallyTypedField_fieldAccess() { injectModule.injectObjects(testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess); assertSame(testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess.getToInjectSuper(), testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess.getInjectOn().getToInjectSuper()); assertSame(testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess.getToInjectSub(), testInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess.getInjectOn().getToInjectSub()); } /** * Tests the case where the target property of the object to inject on belongs to the superclass */ @Test public void testInjectIntoByType_targetPropertyOnSuperClass() { injectModule.injectObjects(testInjectIntoByType_targetPropertyOnSuperClass); assertSame(testInjectIntoByType_targetPropertyOnSuperClass.getToInject(), testInjectIntoByType_targetPropertyOnSuperClass.getInjectOn().getToInject()); } /** * Tests the case where the target property of the object to inject on belongs to the superclass, using field access */ @Test public void testInjectIntoByType_targetPropertyOnSuperClass_fieldAccess() { injectModule.injectObjects(testInjectIntoByType_targetPropertyOnSuperClass_fieldAccess); assertSame(testInjectIntoByType_targetPropertyOnSuperClass_fieldAccess.getToInject(), testInjectIntoByType_targetPropertyOnSuperClass_fieldAccess.getInjectOn().getToInject()); } public class TestInjectIntoByTypeExplicitTarget { @InjectIntoByType(target = "injectOn", propertyAccess = PropertyAccess.SETTER) private ToInjectSuper toInject; private InjectOn injectOn; public TestInjectIntoByTypeExplicitTarget() { toInject = new ToInjectSuper(); injectOn = new InjectOn(); } public ToInjectSuper getToInject() { return toInject; } public InjectOn getInjectOn() { return injectOn; } } public class TestInjectIntoByTypeFieldAccess { @InjectIntoByType(propertyAccess = PropertyAccess.FIELD) private ToInjectSuper toInject; @TestedObject private InjectOnField injectOnField; public TestInjectIntoByTypeFieldAccess() { toInject = new ToInjectSuper(); injectOnField = new InjectOnField(); } public ToInjectSuper getToInject() { return toInject; } public InjectOnField getInjectOnField() { return injectOnField; } } public class TestInjectIntoByTypeAnnotatedTarget { @InjectIntoByType(propertyAccess = PropertyAccess.SETTER) private ToInjectSuper toInject; @TestedObject private InjectOn injectOn1; @TestedObject private InjectOn injectOn2; public TestInjectIntoByTypeAnnotatedTarget() { toInject = new ToInjectSuper(); injectOn1 = new InjectOn(); injectOn2 = new InjectOn(); } public ToInjectSuper getToInject() { return toInject; } public InjectOn getInjectOn1() { return injectOn1; } public InjectOn getInjectOn2() { return injectOn2; } } public class TestInjectIntoByType_targetPropertyIsSuperType { @InjectIntoByType(propertyAccess = PropertyAccess.SETTER) private ToInjectSub toInject; @TestedObject private InjectOn injectOn; public TestInjectIntoByType_targetPropertyIsSuperType() { toInject = new ToInjectSub(); injectOn = new InjectOn(); } public ToInjectSub getToInject() { return toInject; } public InjectOn getInjectOn() { return injectOn; } } public class TestInjectIntoByType_targetPropertyIsSuperType_fieldAccess { @InjectIntoByType(propertyAccess = PropertyAccess.FIELD) private ToInjectSub toInject; @TestedObject private InjectOnField injectOn; public TestInjectIntoByType_targetPropertyIsSuperType_fieldAccess() { toInject = new ToInjectSub(); injectOn = new InjectOnField(); } public ToInjectSub getToInject() { return toInject; } public InjectOnField getInjectOn() { return injectOn; } } public class TestInjectIntoByTypeToMostSpecificallyTypedProperty { @InjectIntoByType(propertyAccess = PropertyAccess.SETTER) private ToInjectSuper toInjectSuper; @InjectIntoByType(propertyAccess = PropertyAccess.SETTER) private ToInjectSub toInjectSub; @TestedObject private InjectOnSuperSub injectOn; public TestInjectIntoByTypeToMostSpecificallyTypedProperty() { toInjectSuper = new ToInjectSuper(); toInjectSub = new ToInjectSub(); injectOn = new InjectOnSuperSub(); } public ToInjectSuper getToInjectSuper() { return toInjectSuper; } public ToInjectSub getToInjectSub() { return toInjectSub; } public InjectOnSuperSub getInjectOn() { return injectOn; } } public class TestInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess { @InjectIntoByType(propertyAccess = PropertyAccess.FIELD) private ToInjectSuper toInjectSuper; @InjectIntoByType(propertyAccess = PropertyAccess.FIELD) private ToInjectSub toInjectSub; @TestedObject private InjectOnSuperSubFieldAccess injectOn; public TestInjectIntoByTypeToMostSpecificallyTypedProperty_fieldAccess() { toInjectSuper = new ToInjectSuper(); toInjectSub = new ToInjectSub(); injectOn = new InjectOnSuperSubFieldAccess(); } public ToInjectSuper getToInjectSuper() { return toInjectSuper; } public ToInjectSub getToInjectSub() { return toInjectSub; } public InjectOnSuperSubFieldAccess getInjectOn() { return injectOn; } } public class TestInjectIntoByType_targetPropertyOnSuperClass { @InjectIntoByType(propertyAccess = PropertyAccess.SETTER) private ToInjectSuper toInject; @TestedObject private InjectOn_subClass injectOn; public TestInjectIntoByType_targetPropertyOnSuperClass() { toInject = new ToInjectSuper(); injectOn = new InjectOn_subClass(); } public ToInjectSuper getToInject() { return toInject; } public InjectOn_subClass getInjectOn() { return injectOn; } } public class TestInjectIntoByType_targetPropertyOnSuperClass_fieldAccess { @InjectIntoByType(propertyAccess = PropertyAccess.FIELD) private ToInjectSuper toInject; @TestedObject private InjectOn_subClass injectOn; public TestInjectIntoByType_targetPropertyOnSuperClass_fieldAccess() { toInject = new ToInjectSuper(); injectOn = new InjectOn_subClass(); } public ToInjectSuper getToInject() { return toInject; } public InjectOn_subClass getInjectOn() { return injectOn; } } /** * Object to inject, superclass */ public class ToInjectSuper { } /** * Object to inject, subclass */ public class ToInjectSub extends ToInjectSuper { } /** * Object to inject into */ public class InjectOn { private ToInjectSuper toInject; public ToInjectSuper getToInject() { return toInject; } public void setToInject(ToInjectSuper toInject) { this.toInject = toInject; } } /** * Object to inject using field access */ public class InjectOnField { private ToInjectSuper toInject; public ToInjectSuper getToInject() { return toInject; } } /** * Object to inject on. Contains properties of a super- and a subtype. */ public class InjectOnSuperSub { private ToInjectSuper toInjectSuper; private ToInjectSub toInjectSub; public ToInjectSuper getToInjectSuper() { return toInjectSuper; } public void setToInjectSuper(ToInjectSuper toInjectSuper) { this.toInjectSuper = toInjectSuper; } public ToInjectSub getToInjectSub() { return toInjectSub; } public void setToInjectSub(ToInjectSub toInjectSub) { this.toInjectSub = toInjectSub; } } /** * Object to inject on using field access. Contains properties of a super- and a subtype. */ public class InjectOnSuperSubFieldAccess { private ToInjectSuper toInjectSuper; private ToInjectSub toInjectSub; public ToInjectSuper getToInjectSuper() { return toInjectSuper; } public ToInjectSub getToInjectSub() { return toInjectSub; } } /** * Superclass of object to inject into */ public class InjectOn_superClass { private ToInjectSuper toInject; public ToInjectSuper getToInject() { return toInject; } public void setToInject(ToInjectSuper toInject) { this.toInject = toInject; } } /** * Superclass of object to inject into */ public class InjectOn_subClass extends InjectOn_superClass { } }