1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6 package org.mockito.internal.util.reflection; 7 8 9 import org.junit.After; 10 import org.junit.Test; 11 import org.junit.runner.RunWith; 12 import org.mockito.Matchers; 13 import org.mockito.Mock; 14 import org.mockito.exceptions.base.MockitoException; 15 import org.mockito.internal.util.reflection.FieldInitializer.ConstructorArgumentResolver; 16 import org.mockito.internal.util.reflection.FieldInitializer.ParameterizedConstructorInstantiator; 17 import org.mockito.junit.MockitoJUnitRunner; 18 19 import java.io.IOException; 20 import java.lang.reflect.Field; 21 import java.util.Map; 22 import java.util.Observer; 23 import java.util.Set; 24 25 import static org.assertj.core.api.Assertions.assertThat; 26 import static org.junit.Assert.assertNotNull; 27 import static org.junit.Assert.fail; 28 import static org.mockito.BDDMockito.given; 29 import static org.mockito.Mockito.mock; 30 31 32 @SuppressWarnings("unchecked") 33 @RunWith(MockitoJUnitRunner.class) 34 public class ParameterizedConstructorInstantiatorTest { 35 36 private Set<?> whateverForNow; 37 private OneConstructor withOneConstructor; 38 private MultipleConstructor withMultipleConstructor; 39 private NoArgConstructor withNoArgConstructor; 40 private ThrowingConstructor withThrowingConstructor; 41 private VarargConstructor withVarargConstructor; 42 43 @After 44 public void ensure_instances_to_create_are_null() { 45 withMultipleConstructor = null; 46 withOneConstructor = null; 47 withNoArgConstructor = null; 48 withThrowingConstructor = null; 49 withVarargConstructor = null; 50 } 51 52 @Mock private ConstructorArgumentResolver resolver; 53 54 @Test 55 public void should_be_created_with_an_argument_resolver() throws Exception { 56 new ParameterizedConstructorInstantiator(this, field("whateverForNow"), resolver); 57 } 58 59 @Test 60 public void should_fail_if_no_parameterized_constructor_found___excluding_inner_and_others_kind_of_types() throws Exception { 61 try { 62 new ParameterizedConstructorInstantiator(this, field("withNoArgConstructor"), resolver).instantiate(); 63 fail(); 64 } catch (MockitoException me) { 65 assertThat(me.getMessage()).contains("no parameterized constructor").contains("withNoArgConstructor").contains("NoArgConstructor"); 66 } 67 } 68 69 @Test 70 public void should_instantiate_type_if_resolver_provide_matching_types() throws Exception { 71 Observer observer = mock(Observer.class); 72 Map map = mock(Map.class); 73 given(resolver.resolveTypeInstances(Matchers.<Class<?>[]>anyVararg())).willReturn(new Object[]{ observer, map }); 74 75 new ParameterizedConstructorInstantiator(this, field("withMultipleConstructor"), resolver).instantiate(); 76 77 assertNotNull(withMultipleConstructor); 78 assertNotNull(withMultipleConstructor.observer); 79 assertNotNull(withMultipleConstructor.map); 80 } 81 82 @Test 83 public void should_fail_if_an_argument_instance_type_do_not_match_wanted_type() throws Exception { 84 Observer observer = mock(Observer.class); 85 Set<?> wrongArg = mock(Set.class); 86 given(resolver.resolveTypeInstances(Matchers.<Class<?>[]>anyVararg())).willReturn(new Object[]{ observer, wrongArg }); 87 88 try { 89 new ParameterizedConstructorInstantiator(this, field("withMultipleConstructor"), resolver).instantiate(); 90 fail(); 91 } catch (MockitoException e) { 92 assertThat(e.getMessage()).contains("argResolver").contains("incorrect types"); 93 } 94 } 95 96 @Test 97 public void should_report_failure_if_constructor_throws_exception() throws Exception { 98 given(resolver.resolveTypeInstances(Matchers.<Class<?>[]>anyVararg())).willReturn(new Object[]{ null }); 99 100 try { 101 new ParameterizedConstructorInstantiator(this, field("withThrowingConstructor"), resolver).instantiate(); 102 fail(); 103 } catch (MockitoException e) { 104 assertThat(e.getMessage()).contains("constructor").contains("raised an exception"); 105 } 106 } 107 108 @Test 109 public void should_instantiate_type_with_vararg_constructor() throws Exception { 110 Observer[] vararg = new Observer[] { }; 111 given(resolver.resolveTypeInstances(Matchers.<Class<?>[]>anyVararg())).willReturn(new Object[]{ "", vararg}); 112 113 new ParameterizedConstructorInstantiator(this, field("withVarargConstructor"), resolver).instantiate(); 114 115 assertNotNull(withVarargConstructor); 116 } 117 118 private Field field(String fieldName) throws NoSuchFieldException { 119 Field field = this.getClass().getDeclaredField(fieldName); 120 field.setAccessible(true); 121 return field; 122 } 123 124 private static class NoArgConstructor { 125 NoArgConstructor() { } 126 } 127 128 private static class OneConstructor { 129 public OneConstructor(Observer observer) { } 130 } 131 132 private static class ThrowingConstructor { 133 public ThrowingConstructor(Observer observer) throws IOException { throw new IOException(); } 134 } 135 136 private static class MultipleConstructor extends OneConstructor { 137 Observer observer; 138 Map map; 139 140 public MultipleConstructor(Observer observer) { this(observer, null); } 141 public MultipleConstructor(Observer observer, Map map) { 142 super(observer); 143 this.observer = observer; 144 this.map = map; 145 } 146 } 147 148 private static class VarargConstructor { 149 VarargConstructor(String whatever, Observer... observers) { } 150 } 151 } 152