Skip to content

Commit 7c9877a

Browse files
akutscheraNylle
authored andcommitted
fix: use values from "with" in constructor
Refs: #87
1 parent bc460d0 commit 7c9877a

File tree

5 files changed

+46
-14
lines changed

5 files changed

+46
-14
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
<dependency>
7676
<groupId>org.assertj</groupId>
7777
<artifactId>assertj-core</artifactId>
78-
<version>3.11.1</version>
78+
<version>3.23.1</version>
7979
<scope>test</scope>
8080
</dependency>
8181
<dependency>

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.lang.reflect.InvocationTargetException;
1212
import java.lang.reflect.Method;
1313
import java.lang.reflect.Modifier;
14+
import java.lang.reflect.Parameter;
1415
import java.lang.reflect.Proxy;
1516
import java.util.ArrayDeque;
1617
import java.util.ArrayList;
@@ -49,10 +50,6 @@ public InstanceFactory(SpecimenFactory specimenFactory) {
4950
this.random = new Random();
5051
}
5152

52-
public <T> T construct(final SpecimenType<T> type) {
53-
return construct(type, new CustomizationContext(true));
54-
}
55-
5653
public <T> T construct(final SpecimenType<T> type, CustomizationContext customizationContext) {
5754
var constructors = type.getDeclaredConstructors()
5855
.stream()
@@ -115,15 +112,22 @@ public <G, T extends Collection<G>> T createCollection(final SpecimenType<T> typ
115112
private <T> T construct(final SpecimenType<T> type, final Constructor<?> constructor, CustomizationContext customizationContext) {
116113
try {
117114
constructor.setAccessible(true);
118-
return (T) constructor.newInstance(stream(constructor.getGenericParameterTypes())
119-
.map(t -> specimenFactory.build(SpecimenType.fromClass(t)))
120-
.map(s -> s.create(customizationContext, new Annotation[0]))
115+
return (T) constructor.newInstance(stream(constructor.getParameters())
116+
.map(p -> createParameter(p, customizationContext))
121117
.toArray());
122118
} catch (Exception e) {
123119
return manufacture(type, customizationContext);
124120
}
125121
}
126122

123+
private Object createParameter(Parameter parameter, CustomizationContext customizationContext) {
124+
if (customizationContext.getCustomFields().containsKey(parameter.getName())) {
125+
return customizationContext.getCustomFields().get(parameter.getName());
126+
}
127+
var specimen = specimenFactory.build(SpecimenType.fromClass(parameter.getParameterizedType()));
128+
return specimen.create(customizationContext, new Annotation[0]);
129+
}
130+
127131
private <T> T createProxyForAbstract(final SpecimenType<T> type, final Map<String, ISpecimen<?>> specimens) {
128132
try {
129133
var factory = new ProxyFactory();

src/main/java/com/github/nylle/javafixture/specimen/GenericSpecimen.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public GenericSpecimen(SpecimenType<T> type, Context context, SpecimenFactory sp
6161
@Override
6262
public T create(CustomizationContext customizationContext, Annotation[] annotations) {
6363
if (type.asClass().equals(Class.class)) {
64-
return (T) specimens.entrySet().stream().findFirst().get().getValue().create(customizationContext, new Annotation[0]).getClass();
64+
return (T) specimens.entrySet().stream().findFirst().get().getValue().create(customizationContext, new Annotation[0]).getClass();
6565
}
6666

6767
if (context.isCached(type)) {
@@ -73,7 +73,7 @@ public T create(CustomizationContext customizationContext, Annotation[] annotati
7373
}
7474

7575
if (customizationContext.useRandomConstructor()) {
76-
return context.cached(type, instanceFactory.construct(type));
76+
return context.cached(type, instanceFactory.construct(type, customizationContext));
7777
}
7878

7979
return populate(customizationContext);
@@ -92,8 +92,8 @@ private T populate(CustomizationContext customizationContext) {
9292
specimens.getOrDefault(
9393
field.getGenericType().getTypeName(),
9494
specimenFactory.build(SpecimenType.fromClass(field.getType()))).create(new CustomizationContext(List.of(), Map.of()), new Annotation[0]))));
95-
} catch (SpecimenException ex ) {
96-
return context.overwrite(type, instanceFactory.construct(type));
95+
} catch (SpecimenException ex) {
96+
return context.overwrite(type, instanceFactory.construct(type, customizationContext));
9797
}
9898
return result;
9999
}

src/main/java/com/github/nylle/javafixture/specimen/ObjectSpecimen.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public T create(CustomizationContext customizationContext, Annotation[] annotati
5151
}
5252

5353
if (customizationContext.useRandomConstructor()) {
54-
return context.cached(type, instanceFactory.construct(type));
54+
return context.cached(type, instanceFactory.construct(type, customizationContext));
5555
}
5656

5757
return populate(customizationContext);
@@ -71,7 +71,7 @@ private T populate(CustomizationContext customizationContext) {
7171
field.getGenericType().getTypeName(),
7272
specimenFactory.build(SpecimenType.fromClass(field.getGenericType()))).create(new CustomizationContext(List.of(), Map.of()), field.getAnnotations()))));
7373
} catch (SpecimenException ex ) {
74-
return context.overwrite(type, instanceFactory.construct(type));
74+
return context.overwrite(type, instanceFactory.construct(type, customizationContext));
7575
}
7676
return result;
7777
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.nylle.javafixture;
22

3+
import com.github.nylle.javafixture.testobjects.TestObject;
34
import com.github.nylle.javafixture.testobjects.factorymethod.ConstructorExceptionAndFactoryMethod;
45
import com.github.nylle.javafixture.testobjects.factorymethod.FactoryMethodWithArgument;
56
import com.github.nylle.javafixture.testobjects.factorymethod.FactoryMethodWithGenericArgument;
@@ -113,6 +114,33 @@ void fallbackToFactoryMethodWhenConstructorThrowsException() {
113114

114115
assertThat(result.getValue()).isNotNull();
115116
}
117+
118+
@Test
119+
@DisplayName("arguments can be customized")
120+
void argumentsCanBeCustomized() {
121+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
122+
123+
var customizationContext = new CustomizationContext(true);
124+
// use arg0, because .class files do not store formal parameter names by default
125+
customizationContext.getCustomFields().put("arg0", "customized");
126+
TestObject result = sut.construct(fromClass(TestObject.class), customizationContext);
127+
128+
assertThat(result.getValue()).isEqualTo("customized");
129+
}
130+
131+
@Test
132+
@DisplayName("constructor arguments are cached")
133+
void constructorArgumentsAreCached() {
134+
var sut = new InstanceFactory(new SpecimenFactory(new Context(Configuration.configure())));
135+
136+
var customizationContext = new CustomizationContext(true);
137+
TestObject first = sut.construct(fromClass(TestObject.class), customizationContext);
138+
TestObject second = sut.construct(fromClass(TestObject.class), customizationContext);
139+
140+
assertThat(first.getIntegers()).usingRecursiveComparison().isEqualTo(second.getIntegers());
141+
assertThat(first.getStrings()).usingRecursiveComparison().isEqualTo(second.getStrings());
142+
assertThat(first.getValue()).as("primitives are never cached").isNotEqualTo(second.getValue());
143+
}
116144
}
117145

118146
@Nested

0 commit comments

Comments
 (0)