Skip to content

Commit 7332671

Browse files
committed
fix: use parameter types when present
Refs: JF-67
1 parent 0fcda14 commit 7332671

File tree

6 files changed

+134
-32
lines changed

6 files changed

+134
-32
lines changed

src/main/java/com/github/nylle/javafixture/InstanceFactory.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.lang.reflect.Method;
1313
import java.lang.reflect.Modifier;
1414
import java.lang.reflect.Proxy;
15+
import java.lang.reflect.Type;
1516
import java.util.ArrayDeque;
1617
import java.util.ArrayList;
1718
import java.util.Collection;
@@ -65,7 +66,7 @@ public <T> T manufacture(final SpecimenType<T> type) {
6566
var results = type.getFactoryMethods()
6667
.stream()
6768
.filter(x -> Modifier.isPublic(x.getModifiers()))
68-
.map(x -> manufactureOrNull(x))
69+
.map(x -> manufactureOrNull(x, type))
6970
.filter(x -> x != null)
7071
.map(x -> (T) x)
7172
.collect(toList());
@@ -93,7 +94,7 @@ public <T> Object proxy(final SpecimenType<T> type, final Map<String, ISpecimen<
9394
if (type.isInterface()) {
9495
return Proxy.newProxyInstance(
9596
type.asClass().getClassLoader(),
96-
new Class[] { type.asClass() },
97+
new Class[]{type.asClass()},
9798
new ProxyInvocationHandler(specimenFactory, specimens));
9899
}
99100

@@ -126,9 +127,15 @@ private <T> T createProxyForAbstract(final SpecimenType<T> type, final Map<Strin
126127
}
127128
}
128129

129-
private <T> T manufactureOrNull(final Method method) {
130+
private <T> T manufactureOrNull(final Method method, SpecimenType<T> type) {
130131
try {
131-
return (T) method.invoke(stream(method.getGenericParameterTypes())
132+
Type[] parameterTypes;
133+
if (type.isParameterized()) {
134+
parameterTypes = type.getGenericTypeArguments();
135+
} else {
136+
parameterTypes = method.getGenericParameterTypes();
137+
}
138+
return (T) method.invoke(null, stream(parameterTypes)
132139
.map(t -> specimenFactory.build(SpecimenType.fromClass(t)))
133140
.map(s -> s.create(new Annotation[0]))
134141
.toArray());
@@ -185,7 +192,8 @@ private <G, T extends Collection<G>> T createCollectionFromInterfaceType(final C
185192
private <G, T extends Collection<G>> T createCollectionFromConcreteType(final SpecimenType<T> type) {
186193
try {
187194
return type.asClass().getDeclaredConstructor().newInstance();
188-
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
195+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
196+
NoSuchMethodException e) {
189197
throw new SpecimenException("Unable to create collection of type " + type.getName(), e);
190198
}
191199
}

src/test/java/com/github/nylle/javafixture/InstanceFactoryTest.java

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.github.nylle.javafixture;
22

33
import com.github.nylle.javafixture.testobjects.TestObjectWithGenericConstructor;
4-
import com.github.nylle.javafixture.testobjects.TestObjectWithNonPublicFactoryMethods;
4+
import com.github.nylle.javafixture.testobjects.factorymethod.TestObjectWithNonPublicFactoryMethods;
55
import com.github.nylle.javafixture.testobjects.TestObjectWithPrivateConstructor;
6+
import com.github.nylle.javafixture.testobjects.factorymethod.FactoryMethodWithArgument;
7+
import com.github.nylle.javafixture.testobjects.factorymethod.FactoryMethodWithGenericArgument;
8+
import com.github.nylle.javafixture.testobjects.factorymethod.FactoryMethodWithoutArgument;
9+
import org.junit.jupiter.api.DisplayName;
610
import org.junit.jupiter.api.Nested;
711
import org.junit.jupiter.api.Test;
812

@@ -76,14 +80,50 @@ void canCreateInstanceFromAbstractClassUsingFactoryMethod() {
7680
assertThat(actual).isInstanceOf(Charset.class);
7781
}
7882

79-
@Test
80-
void canOnlyUsePublicFactoryMethods() {
81-
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
83+
@Nested
84+
@DisplayName("when manufacturing using factory methods")
85+
class FactoryMethods {
86+
@Test
87+
@DisplayName("only public methods will be used")
88+
void canOnlyUsePublicFactoryMethods() {
89+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
90+
91+
assertThatExceptionOfType(SpecimenException.class)
92+
.isThrownBy(() -> sut.manufacture(fromClass(TestObjectWithNonPublicFactoryMethods.class)))
93+
.withMessageContaining("Cannot manufacture class")
94+
.withNoCause();
95+
}
96+
97+
@Test
98+
@DisplayName("method arguments are used")
99+
void factoryMethodWithArgument() {
100+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
101+
102+
FactoryMethodWithArgument result = sut.manufacture(fromClass(FactoryMethodWithArgument.class));
103+
104+
assertThat(result.getValue()).isNotNull();
105+
}
106+
107+
@Test
108+
@DisplayName("method without arguments is used")
109+
void factoryMethodWithoutArgument() {
110+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
111+
112+
FactoryMethodWithoutArgument result = sut.manufacture(fromClass(FactoryMethodWithoutArgument.class));
113+
114+
assertThat(result.getValue()).isEqualTo(42);
115+
}
116+
117+
@Test
118+
@DisplayName("method with generic arguments is used")
119+
void factoryMethodWithGenericArgument() {
120+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
121+
122+
FactoryMethodWithGenericArgument result = sut.manufacture(new SpecimenType<FactoryMethodWithGenericArgument<Integer>>() {});
123+
124+
assertThat(result.getValue()).isNotNull();
125+
}
82126

83-
assertThatExceptionOfType(SpecimenException.class)
84-
.isThrownBy(() -> sut.manufacture(fromClass(TestObjectWithNonPublicFactoryMethods.class)))
85-
.withMessageContaining("Cannot manufacture class")
86-
.withNoCause();
87127
}
88128

89129
@Nested
@@ -93,7 +133,7 @@ class CreateCollectionReturns {
93133
void arrayListFromCollectionInterface() {
94134
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
95135

96-
var actual = sut.createCollection(new SpecimenType<Collection<String>>(){});
136+
var actual = sut.createCollection(new SpecimenType<Collection<String>>() {});
97137

98138
assertThat(actual).isInstanceOf(ArrayList.class);
99139
assertThat(actual).isEmpty();
@@ -103,7 +143,7 @@ void arrayListFromCollectionInterface() {
103143
void arrayListFromListInterface() {
104144
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
105145

106-
var actual = sut.createCollection(new SpecimenType<List<String>>(){});
146+
var actual = sut.createCollection(new SpecimenType<List<String>>() {});
107147

108148
assertThat(actual).isInstanceOf(ArrayList.class);
109149
assertThat(actual).isEmpty();
@@ -113,7 +153,7 @@ void arrayListFromListInterface() {
113153
void treeSetFromNavigableSetInterface() {
114154
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
115155

116-
var actual = sut.createCollection(new SpecimenType<NavigableSet<String>>(){});
156+
var actual = sut.createCollection(new SpecimenType<NavigableSet<String>>() {});
117157

118158
assertThat(actual).isInstanceOf(TreeSet.class);
119159
assertThat(actual).isEmpty();
@@ -123,7 +163,7 @@ void treeSetFromNavigableSetInterface() {
123163
void treeSetFromSortedSetInterface() {
124164
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
125165

126-
var actual = sut.createCollection(new SpecimenType<SortedSet<String>>(){});
166+
var actual = sut.createCollection(new SpecimenType<SortedSet<String>>() {});
127167

128168
assertThat(actual).isInstanceOf(TreeSet.class);
129169
assertThat(actual).isEmpty();
@@ -133,7 +173,7 @@ void treeSetFromSortedSetInterface() {
133173
void hashSetFromSetInterface() {
134174
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
135175

136-
var actual = sut.createCollection(new SpecimenType<Set<String>>(){});
176+
var actual = sut.createCollection(new SpecimenType<Set<String>>() {});
137177

138178
assertThat(actual).isInstanceOf(HashSet.class);
139179
assertThat(actual).isEmpty();
@@ -143,7 +183,7 @@ void hashSetFromSetInterface() {
143183
void linkedBlockingDequeFromBlockingDequeInterface() {
144184
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
145185

146-
var actual = sut.createCollection(new SpecimenType<BlockingDeque<String>>(){});
186+
var actual = sut.createCollection(new SpecimenType<BlockingDeque<String>>() {});
147187

148188
assertThat(actual).isInstanceOf(LinkedBlockingDeque.class);
149189
assertThat(actual).isEmpty();
@@ -153,7 +193,7 @@ void linkedBlockingDequeFromBlockingDequeInterface() {
153193
void arrayDequeFromDequeInterface() {
154194
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
155195

156-
var actual = sut.createCollection(new SpecimenType<Deque<String>>(){});
196+
var actual = sut.createCollection(new SpecimenType<Deque<String>>() {});
157197

158198
assertThat(actual).isInstanceOf(ArrayDeque.class);
159199
assertThat(actual).isEmpty();
@@ -163,7 +203,7 @@ void arrayDequeFromDequeInterface() {
163203
void linkedTransferQueueFromTransferQueueInterface() {
164204
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
165205

166-
var actual = sut.createCollection(new SpecimenType<TransferQueue<String>>(){});
206+
var actual = sut.createCollection(new SpecimenType<TransferQueue<String>>() {});
167207

168208
assertThat(actual).isInstanceOf(LinkedTransferQueue.class);
169209
assertThat(actual).isEmpty();
@@ -173,7 +213,7 @@ void linkedTransferQueueFromTransferQueueInterface() {
173213
void linkedBlockingQueueFromBlockingQueueInterface() {
174214
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
175215

176-
var actual = sut.createCollection(new SpecimenType<BlockingQueue<String>>(){});
216+
var actual = sut.createCollection(new SpecimenType<BlockingQueue<String>>() {});
177217

178218
assertThat(actual).isInstanceOf(LinkedBlockingQueue.class);
179219
assertThat(actual).isEmpty();
@@ -183,7 +223,7 @@ void linkedBlockingQueueFromBlockingQueueInterface() {
183223
void linkedListFromQueueInterface() {
184224
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
185225

186-
var actual = sut.createCollection(new SpecimenType<Queue<String>>(){});
226+
var actual = sut.createCollection(new SpecimenType<Queue<String>>() {});
187227

188228
assertThat(actual).isInstanceOf(LinkedList.class);
189229
assertThat(actual).isEmpty();
@@ -193,7 +233,7 @@ void linkedListFromQueueInterface() {
193233
void arrayList() {
194234
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
195235

196-
var actual = sut.createCollection(new SpecimenType<ArrayList<String>>(){});
236+
var actual = sut.createCollection(new SpecimenType<ArrayList<String>>() {});
197237

198238
assertThat(actual).isInstanceOf(ArrayList.class);
199239
assertThat(actual).isEmpty();
@@ -203,7 +243,7 @@ void arrayList() {
203243
void treeSet() {
204244
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
205245

206-
var actual = sut.createCollection(new SpecimenType<TreeSet<String>>(){});
246+
var actual = sut.createCollection(new SpecimenType<TreeSet<String>>() {});
207247

208248
assertThat(actual).isInstanceOf(TreeSet.class);
209249
assertThat(actual).isEmpty();
@@ -213,7 +253,7 @@ void treeSet() {
213253
void hashSet() {
214254
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
215255

216-
var actual = sut.createCollection(new SpecimenType<HashSet<String>>(){});
256+
var actual = sut.createCollection(new SpecimenType<HashSet<String>>() {});
217257

218258
assertThat(actual).isInstanceOf(HashSet.class);
219259
assertThat(actual).isEmpty();
@@ -223,7 +263,7 @@ void hashSet() {
223263
void linkedBlockingDeque() {
224264
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
225265

226-
var actual = sut.createCollection(new SpecimenType<LinkedBlockingDeque<String>>(){});
266+
var actual = sut.createCollection(new SpecimenType<LinkedBlockingDeque<String>>() {});
227267

228268
assertThat(actual).isInstanceOf(LinkedBlockingDeque.class);
229269
assertThat(actual).isEmpty();
@@ -233,7 +273,7 @@ void linkedBlockingDeque() {
233273
void arrayDeque() {
234274
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
235275

236-
var actual = sut.createCollection(new SpecimenType<ArrayDeque<String>>(){});
276+
var actual = sut.createCollection(new SpecimenType<ArrayDeque<String>>() {});
237277

238278
assertThat(actual).isInstanceOf(ArrayDeque.class);
239279
assertThat(actual).isEmpty();
@@ -243,7 +283,7 @@ void arrayDeque() {
243283
void linkedTransferQueue() {
244284
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
245285

246-
var actual = sut.createCollection(new SpecimenType<LinkedTransferQueue<String>>(){});
286+
var actual = sut.createCollection(new SpecimenType<LinkedTransferQueue<String>>() {});
247287

248288
assertThat(actual).isInstanceOf(LinkedTransferQueue.class);
249289
assertThat(actual).isEmpty();
@@ -253,7 +293,7 @@ void linkedTransferQueue() {
253293
void linkedBlockingQueue() {
254294
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
255295

256-
var actual = sut.createCollection(new SpecimenType<LinkedBlockingQueue<String>>(){});
296+
var actual = sut.createCollection(new SpecimenType<LinkedBlockingQueue<String>>() {});
257297

258298
assertThat(actual).isInstanceOf(LinkedBlockingQueue.class);
259299
assertThat(actual).isEmpty();
@@ -263,7 +303,7 @@ void linkedBlockingQueue() {
263303
void linkedList() {
264304
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
265305

266-
var actual = sut.createCollection(new SpecimenType<LinkedList<String>>(){});
306+
var actual = sut.createCollection(new SpecimenType<LinkedList<String>>() {});
267307

268308
assertThat(actual).isInstanceOf(LinkedList.class);
269309
assertThat(actual).isEmpty();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.nylle.javafixture.testobjects.factorymethod;
2+
3+
public class FactoryMethodWithArgument {
4+
5+
private int value;
6+
7+
private FactoryMethodWithArgument(int value) {
8+
this.value = value;
9+
}
10+
11+
public static FactoryMethodWithArgument factoryMethod(int value) {
12+
return new FactoryMethodWithArgument(value);
13+
}
14+
15+
public int getValue() {
16+
return value;
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.nylle.javafixture.testobjects.factorymethod;
2+
3+
public class FactoryMethodWithGenericArgument<T> {
4+
5+
private T value;
6+
7+
private FactoryMethodWithGenericArgument(T value) {
8+
this.value = value;
9+
}
10+
11+
public static <T> FactoryMethodWithGenericArgument<T> factoryMethod(T value) {
12+
return new FactoryMethodWithGenericArgument(value);
13+
}
14+
15+
public T getValue() {
16+
return value;
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.github.nylle.javafixture.testobjects.factorymethod;
2+
3+
public class FactoryMethodWithoutArgument {
4+
5+
private int value;
6+
7+
private FactoryMethodWithoutArgument(int value) {
8+
this.value = value;
9+
}
10+
11+
public static FactoryMethodWithoutArgument factoryMethod() {
12+
return new FactoryMethodWithoutArgument(42);
13+
}
14+
15+
public int getValue() {
16+
return value;
17+
}
18+
}

src/test/java/com/github/nylle/javafixture/testobjects/TestObjectWithNonPublicFactoryMethods.java renamed to src/test/java/com/github/nylle/javafixture/testobjects/factorymethod/TestObjectWithNonPublicFactoryMethods.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.nylle.javafixture.testobjects;
1+
package com.github.nylle.javafixture.testobjects.factorymethod;
22

33
public class TestObjectWithNonPublicFactoryMethods {
44
private String value;

0 commit comments

Comments
 (0)