1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.stubbing.defaultanswers; 6 7 import org.junit.Test; 8 9 import java.util.Iterator; 10 import java.util.List; 11 import java.util.Map; 12 import java.util.Set; 13 14 import static org.assertj.core.api.Assertions.assertThat; 15 import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 16 import static org.mockito.Mockito.mock; 17 18 @SuppressWarnings("unused") 19 public class ReturnsGenericDeepStubsTest { 20 interface ListOfInteger extends List<Integer> {} 21 22 interface AnotherListOfInteger extends ListOfInteger {} 23 24 interface GenericsNest<K extends Comparable<K> & Cloneable> extends Map<K, Set<Number>> { remove(Object key)25 Set<Number> remove(Object key); // override with fixed ParameterizedType returningWildcard()26 List<? super Number> returningWildcard(); returningNonMockableNestedGeneric()27 Map<String, K> returningNonMockableNestedGeneric(); returningK()28 K returningK(); paramTypeWithTypeParams()29 <O extends K> List<O> paramTypeWithTypeParams(); twoTypeParams(S s)30 <S extends Appendable, T extends S> T twoTypeParams(S s); typeVarWithTypeParams()31 <O extends K> O typeVarWithTypeParams(); returnsNormalType()32 Number returnsNormalType(); 33 } 34 35 @Test generic_deep_mock_frenzy__look_at_these_chained_calls()36 public void generic_deep_mock_frenzy__look_at_these_chained_calls() throws Exception { 37 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 38 39 Set<? extends Map.Entry<? extends Cloneable, Set<Number>>> entries = mock.entrySet(); 40 Iterator<? extends Map.Entry<? extends Cloneable,Set<Number>>> entriesIterator = mock.entrySet().iterator(); 41 Map.Entry<? extends Cloneable, Set<Number>> nextEntry = mock.entrySet().iterator().next(); 42 43 Cloneable cloneableKey = mock.entrySet().iterator().next().getKey(); 44 Comparable<?> comparableKey = mock.entrySet().iterator().next().getKey(); 45 46 Set<Number> value = mock.entrySet().iterator().next().getValue(); 47 Iterator<Number> numbersIterator = mock.entrySet().iterator().next().getValue().iterator(); 48 Number number = mock.entrySet().iterator().next().getValue().iterator().next(); 49 } 50 51 @Test can_create_mock_from_multiple_type_variable_bounds_when_return_type_of_parameterized_method_is_a_parameterizedtype_that_is_referencing_a_typevar_on_class()52 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 { 53 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 54 55 Cloneable cloneable_bound_that_is_declared_on_typevar_K_in_the_class_which_is_referenced_by_typevar_O_declared_on_the_method = 56 mock.paramTypeWithTypeParams().get(0); 57 Comparable<?> comparable_bound_that_is_declared_on_typevar_K_in_the_class_which_is_referenced_by_typevar_O_declared_on_the_method = 58 mock.paramTypeWithTypeParams().get(0); 59 } 60 61 @Test can_create_mock_from_multiple_type_variable_bounds_when_method_return_type_is_referencing_a_typevar_on_class()62 public void can_create_mock_from_multiple_type_variable_bounds_when_method_return_type_is_referencing_a_typevar_on_class() throws Exception { 63 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 64 65 Cloneable cloneable_bound_of_typevar_K = mock.returningK(); 66 Comparable<?> comparable_bound_of_typevar_K = mock.returningK(); 67 } 68 69 @Test can_create_mock_from_multiple_type_variable_bounds_when_return_type_of_parameterized_method_is_a_typevar_that_is_referencing_a_typevar_on_class()70 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 { 71 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 72 73 Cloneable cloneable_bound_of_typevar_K_referenced_by_typevar_O = (Cloneable) mock.typeVarWithTypeParams(); 74 Comparable<?> comparable_bound_of_typevar_K_referenced_by_typevar_O = (Comparable<?>) mock.typeVarWithTypeParams(); 75 } 76 77 @Test can_create_mock_from_return_types_declared_with_a_bounded_wildcard()78 public void can_create_mock_from_return_types_declared_with_a_bounded_wildcard() throws Exception { 79 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 80 81 List<? super Integer> objects = mock.returningWildcard(); 82 Number type_that_is_the_upper_bound_of_the_wildcard = (Number) mock.returningWildcard().get(45); 83 type_that_is_the_upper_bound_of_the_wildcard.floatValue(); 84 } 85 86 @Test can_still_work_with_raw_type_in_the_return_type()87 public void can_still_work_with_raw_type_in_the_return_type() throws Exception { 88 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 89 90 Number the_raw_type_that_should_be_returned = mock.returnsNormalType(); 91 the_raw_type_that_should_be_returned.floatValue(); 92 } 93 94 @Test will_return_default_value_on_non_mockable_nested_generic()95 public void will_return_default_value_on_non_mockable_nested_generic() throws Exception { 96 GenericsNest<?> genericsNest = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 97 ListOfInteger listOfInteger = mock(ListOfInteger.class, RETURNS_DEEP_STUBS); 98 AnotherListOfInteger anotherListOfInteger = mock(AnotherListOfInteger.class, RETURNS_DEEP_STUBS); 99 100 assertThat(genericsNest.returningNonMockableNestedGeneric().keySet().iterator().next()).isNull(); 101 assertThat(listOfInteger.get(25)).isEqualTo(0); 102 assertThat(anotherListOfInteger.get(25)).isEqualTo(0); 103 } 104 105 @Test(expected = ClassCastException.class) as_expected_fail_with_a_CCE_on_callsite_when_erasure_takes_place_for_example___StringBuilder_is_subject_to_erasure()106 public void as_expected_fail_with_a_CCE_on_callsite_when_erasure_takes_place_for_example___StringBuilder_is_subject_to_erasure() throws Exception { 107 GenericsNest<?> mock = mock(GenericsNest.class, RETURNS_DEEP_STUBS); 108 109 // following assignment needed to create a ClassCastException on the call site (i.e. : here) 110 StringBuilder stringBuilder_assignment_that_should_throw_a_CCE = 111 mock.twoTypeParams(new StringBuilder()).append(2).append(3); 112 } 113 } 114