blob: d91df8c40e600bbefe3828ccd45a33f8848b1ce9 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal.stubbing.defaultanswers;
import org.junit.Test;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
@SuppressWarnings("unused")
public class ReturnsGenericDeepStubsTest {
interface ListOfInteger extends List<Integer> {}
interface AnotherListOfInteger extends ListOfInteger {}
interface GenericsNest<K extends Comparable<K> & Cloneable> extends Map<K, Set<Number>> {
Set<Number> remove(Object key); // override with fixed ParameterizedType
List<? super Number> returningWildcard();
Map<String, K> returningNonMockableNestedGeneric();
K returningK();
<O extends K> List<O> paramTypeWithTypeParams();
<S extends Appendable, T extends S> T twoTypeParams(S s);
<O extends K> O typeVarWithTypeParams();
Number returnsNormalType();
}
@Test
public void generic_deep_mock_frenzy__look_at_these_chained_calls() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
Set<? extends Map.Entry<? extends Cloneable, Set<Number>>> entries = mock.entrySet();
Iterator<? extends Map.Entry<? extends Cloneable,Set<Number>>> entriesIterator = mock.entrySet().iterator();
Map.Entry<? extends Cloneable, Set<Number>> nextEntry = mock.entrySet().iterator().next();
Cloneable cloneableKey = mock.entrySet().iterator().next().getKey();
Comparable<?> comparableKey = mock.entrySet().iterator().next().getKey();
Set<Number> value = mock.entrySet().iterator().next().getValue();
Iterator<Number> numbersIterator = mock.entrySet().iterator().next().getValue().iterator();
Number number = mock.entrySet().iterator().next().getValue().iterator().next();
}
@Test
public void can_create_mock_from_multiple_type_variable_bounds_when_return_type_of_parameterized_method_is_a_parameterizedtype_that_is_referencing_a_typevar_on_class() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
Cloneable cloneable_bound_that_is_declared_on_typevar_K_in_the_class_which_is_referenced_by_typevar_O_declared_on_the_method =
mock.paramTypeWithTypeParams().get(0);
Comparable<?> comparable_bound_that_is_declared_on_typevar_K_in_the_class_which_is_referenced_by_typevar_O_declared_on_the_method =
mock.paramTypeWithTypeParams().get(0);
}
@Test
public void can_create_mock_from_multiple_type_variable_bounds_when_method_return_type_is_referencing_a_typevar_on_class() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
Cloneable cloneable_bound_of_typevar_K = mock.returningK();
Comparable<?> comparable_bound_of_typevar_K = mock.returningK();
}
@Test
public void can_create_mock_from_multiple_type_variable_bounds_when_return_type_of_parameterized_method_is_a_typevar_that_is_referencing_a_typevar_on_class() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
Cloneable cloneable_bound_of_typevar_K_referenced_by_typevar_O = (Cloneable) mock.typeVarWithTypeParams();
Comparable<?> comparable_bound_of_typevar_K_referenced_by_typevar_O = (Comparable<?>) mock.typeVarWithTypeParams();
}
@Test
public void can_create_mock_from_return_types_declared_with_a_bounded_wildcard() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
List<? super Integer> objects = mock.returningWildcard();
Number type_that_is_the_upper_bound_of_the_wildcard = (Number) mock.returningWildcard().get(45);
type_that_is_the_upper_bound_of_the_wildcard.floatValue();
}
@Test
public void can_still_work_with_raw_type_in_the_return_type() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
Number the_raw_type_that_should_be_returned = mock.returnsNormalType();
the_raw_type_that_should_be_returned.floatValue();
}
@Test
public void will_return_default_value_on_non_mockable_nested_generic() throws Exception {
GenericsNest<?> genericsNest = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
ListOfInteger listOfInteger = mock(ListOfInteger.class, RETURNS_DEEP_STUBS);
AnotherListOfInteger anotherListOfInteger = mock(AnotherListOfInteger.class, RETURNS_DEEP_STUBS);
assertThat(genericsNest.returningNonMockableNestedGeneric().keySet().iterator().next()).isNull();
assertThat(listOfInteger.get(25)).isEqualTo(0);
assertThat(anotherListOfInteger.get(25)).isEqualTo(0);
}
@Test(expected = ClassCastException.class)
public void as_expected_fail_with_a_CCE_on_callsite_when_erasure_takes_place_for_example___StringBuilder_is_subject_to_erasure() throws Exception {
GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS);
// following assignment needed to create a ClassCastException on the call site (i.e. : here)
StringBuilder stringBuilder_assignment_that_should_throw_a_CCE =
mock.twoTypeParams(new StringBuilder()).append(2).append(3);
}
}