/*
* Copyright (c) 2006 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
import org.junit.*;
import static org.junit.Assert.*;
public final class TestedClassWithGenericsTest
{
public interface Collaborator<T> { T getValue(); }
@SuppressWarnings("unused")
static class SUTWithUnboundedTypeParameter<T>
{
T value;
final Collaborator<T> collaborator;
final Iterable<Collaborator<T>> collaborators;
Map<T, ?> values;
Callable<T> action1;
Callable<?> action2;
SUTWithUnboundedTypeParameter(Collaborator<T> c) { collaborator = c; collaborators = null; }
SUTWithUnboundedTypeParameter(Iterable<Collaborator<T>> collaborators, Callable<String> action)
{
collaborator = null;
this.collaborators = collaborators;
action2 = action;
}
<V extends CharSequence & Serializable> SUTWithUnboundedTypeParameter(Map<T, V> values, Callable<?> action)
{
collaborator = null;
collaborators = null;
this.values = values;
action2 = action;
}
}
@Tested SUTWithUnboundedTypeParameter<Integer> tested1;
@Injectable final Integer numberToInject = 123;
@Injectable Collaborator<Integer> mockCollaborator;
@Test
public void useSUTCreatedWithConstructorOfSingleGenericParameterAndWithGenericFieldInjectedFromConcreteInjectables()
{
assertSame(mockCollaborator, tested1.collaborator);
assertNull(tested1.collaborators);
assertSame(numberToInject, tested1.value);
assertNull(tested1.action1);
assertNull(tested1.action2);
assertNull(tested1.values);
}
@Test
public void useSUTInstantiatedWithConstructorHavingMultipleGenericParameters(
@Injectable Callable<String> mockAction1, @Injectable Callable<Integer> action1)
{
assertNull(tested1.collaborator);
assertSame(mockCollaborator, tested1.collaborators.iterator().next());
assertSame(mockAction1, tested1.action2);
assertSame(action1, tested1.action1);
assertSame(numberToInject, tested1.value);
assertNull(tested1.values);
}
@Test
public void useSUTInstantiatedWithGenericConstructorParametersInjectedFromConcreteInjectables(
@Injectable Iterable<Collaborator<Integer>> mockCollaborators, @Injectable Callable<String> mockAction)
{
assertNull(tested1.collaborator);
assertSame(mockCollaborators, tested1.collaborators);
assertNull(tested1.action1);
assertSame(mockAction, tested1.action2);
assertSame(numberToInject, tested1.value);
assertNull(tested1.values);
}
@Test
public void useSUTInstantiatedWithGenericConstructor(
@Injectable Callable<?> mockAction, @Injectable Map<Integer, String> mockValues)
{
assertNull(tested1.collaborator);
assertNull(tested1.collaborators);
assertSame(mockValues, tested1.values);
assertNull(tested1.action1);
assertSame(mockAction, tested1.action2);
assertSame(numberToInject, tested1.value);
}
static class GenericClass<T> { T value; }
static class SUTWithBoundedTypeParameter<N extends Number, C extends CharSequence>
{
C textValue;
N numberValue;
GenericClass<N> collaborator;
Callable<C> action;
}
@Tested SUTWithBoundedTypeParameter<Integer, String> tested2;
@Tested SUTWithBoundedTypeParameter<Number, CharSequence> tested3;
@Tested SUTWithBoundedTypeParameter<?, ?> tested4;
@Tested SUTWithBoundedTypeParameter<Long, StringBuilder> tested5;
@Test
public void useSUTDeclaredWithTypeBound(
@Injectable("test") String name, @Injectable Callable<String> textAction,
@Injectable GenericClass<? extends Number> collaborator)
{
assertSame(numberToInject, tested2.numberValue);
assertSame(name, tested2.textValue);
assertSame(collaborator, tested2.collaborator);
assertSame(textAction, tested2.action);
assertSame(numberToInject, tested3.numberValue);
assertSame(name, tested3.textValue);
assertSame(collaborator, tested3.collaborator);
assertSame(textAction, tested3.action);
assertSame(numberToInject, tested4.numberValue);
assertSame(name, tested4.textValue);
assertSame(collaborator, tested4.collaborator);
assertSame(textAction, tested4.action);
assertNull(tested5.numberValue);
assertNull(tested5.textValue);
assertSame(collaborator, tested5.collaborator);
assertNull(tested5.action);
}
@Test
public void useSUTDeclaredWithTypeBoundHavingNonMatchingInjectableWithWildcard(
@Injectable Callable<? extends Number> action)
{
assertNull(tested2.action);
assertNull(tested3.action);
assertNull(tested4.action);
assertNull(tested5.action);
}
static class Base<B> { B dep; }
static class Derived<D> extends Base<D> {}
static final class Concrete extends Derived<Dep> {}
public interface Dep {}
@Injectable final Dep dep = new Dep() {};
@Tested Concrete sut;
@Test
public void useSUTClassExtendingGenericBaseClassWhichExtendsAnotherGenericBaseClassContainingAGenericDependency()
{
assertSame(dep, sut.dep);
}
public static class AnotherDep {}
static class Concrete2 extends Base<AnotherDep> {}
@Tested(fullyInitialized = true) Concrete2 sut2;
@Test
public void useFullyInitializedSUTClassExtendingGenericBaseClass()
{
AnotherDep anotherDep = sut2.dep;
assertNotNull(anotherDep);
}
static class Concrete3 extends Derived<AnotherDep> {}
@Tested(fullyInitialized = true) Concrete3 sut3;
@Test
public void useFullyInitializedSUTClassExtendingGenericClassWhichExtendsAnotherGenericClass()
{
AnotherDep anotherDep = sut3.dep;
assertNotNull(anotherDep);
}
static class TestedClassWithConstructorParameterOfGenericType
{
private final Class<?> aClass;
TestedClassWithConstructorParameterOfGenericType(Class<?> aClass) { this.aClass = aClass; }
}
@Tested final Class<?> aClass = Long.class;
@Tested(fullyInitialized = true) TestedClassWithConstructorParameterOfGenericType tested6;
@Test
public void verifyInstantiationOfClassWithConstructorParameterOfGenericType()
{
assertSame(aClass, tested6.aClass);
}
static class GenericClassWithDependencyUsingTypeParameter<T> { GenericClass<T> dependency; }
@Tested final GenericClass<String> dependency = new GenericClass<String>();
@Tested(fullyInitialized = true) GenericClassWithDependencyUsingTypeParameter<String> tested7;
@Test
public void verifyInstantiationOfGenericClassWithDependencyUsingTypeParameter()
{
assertSame(dependency, tested7.dependency);
}
public interface Interface {}
static class Implementation implements Interface {}
static class Derived2 extends Base<Interface> {}
@Tested Implementation impl;
@Tested(fullyInitialized = true) Derived2 tested;
@Test
public void useTestedObjectOfImplementationTypeForTypeVariableInGenericBaseClass()
{
assertSame(impl, tested.dep);
}
}